1

How do I hand RelayState correctly to Okta-side ACS URLs so that it gets to the IdP as entered?

The Okta-provided ACS URLs for Identity Providers don't handle SP-initiated RelayState as I expect.

I put ?RelayState=hello on an ACS URL and the IdP gets a SAMLRequest with a RelayState of %3FRelayState%3Dhello which decodes to ?RelayState=hello.

If I put ?RelayState= instead then the RelayState with the SAMLRequest is blank as I expect.

I've attached NetworkData.xml which is a capture from Internet Explorer. On line 447 column 53, you can see that the RelayState encoded by Okta to be POSTed to https://fs.research.verafin.local/adfs/ls includes ?RelayState in it.

AD FS's IdP SSO service at https://fs.research.verafin.local/adfs/ls decodes and re-encodes the RelayState preserving the broken value it was given and drops it into a form to be POSTed to https://verafin.oktapreview.com:443/sso/saml2/0oaa25fc86YRTkyb60h7 (Okta ACS URL).

It then redirects to https://verafin.oktapreview.com/?RelayState=hello&fromLogin=true HTTP/1.1

Is this a bug in Okta's ACS implementation?

How do I get Okta ACS URLs to accept RelayState in GET requests (SP initiated SSO with RelayState)?

Steps to Reproduce

  1. Copy the ACS URL from an Identity Provider in Okta
  2. Paste it into the browser with ?RelayState=hello after it
  3. Visit resulting URL

How do I hand RelayState correctly to Okta-side ACS URLs so that it gets to the IdP as entered?

0

2 Answers 2

2

The accepted answer is no longer current, Okta recommends against using fromURI now and recommends using SAML DeepLinks as defined here

Redirect with SAML deep links

Use SAML deep links to automatically redirect the user to an app after successfully authenticating with a third-party IdP. To use deep links, assemble these three parts into a URL:

SP ACS URL
For example: https://{myOktaDomain}.com/sso/saml2/:idpId
The app to which the user is automatically redirected after successfully authenticating with the IdP
For example: /app/:app-location/:appId/sso/saml
Optionally, if the app is an outbound SAML app, you can specify the relayState passed to it.
For example: ?RelayState=:anyUrlEncodedValue

The deep link for the above three parts is: https://{myOktaDomain}.com/sso/saml2/:idpId/app/:app-location/:appId/sso/saml?RelayState=:anyUrlEncodedValue

1
  • This is huge improvement. Thank you for sharing this. Commented Oct 30, 2020 at 0:27
0

You can use fromURI as a query parameter with a minor tweak.

An example with minimal dependencies is a loopback within an Okta Org.

Say you want to get to the admin interface of an Org. It's at:

/home/admin-entry

URL encoded (what you need for RelayState) that is:

%2Fhome%2Fadmin-entry

You can verify this by looking at the URL of the Admin link on the /app/UserHome page.

You create a Identity Provider called loopback in Okta. My example has an ACS URL of:

https://dev-971545.oktapreview.com/auth/saml20/loopback

You create an App that is linked to that Identity Provider called loopback. It has a Single Sign-on URL (visible after clicking View Setup Instructions on the Sign-on tab) of:

https://dev-971545.oktapreview.com/app/independentconsultantdev927755_loopback_1/exkadbfail8okn4W80h7/sso/saml

There are two layers of RelayState:

  1. The app you want Okta to direct you to: in this case the loopback app
  2. The path within that app

Passing the RelayState to an App SSO URL is easy:

https://dev-971545.oktapreview.com/app/independentconsultantdev927755_loopback_1/exkadbfail8okn4W80h7/sso/saml?RelayState=%2Fhome%2Fadmin-entry

Following that URL brings me to the Admin dashboard.

There's no inbound SAML yet. This is all within Okta. Let's add the SAML layer.

The path of that App SSO URL, minus the leading slash (workaround for fromURI) is:

app/independentconsultantdev927755_loopback_1/exkadbfail8okn4W80h7/sso/saml?RelayState=%2Fhome%2Fadmin-entry

We URL encode that to prepare it to be the value of a query parameter:

app%2Findependentconsultantdev927755_loopback_1%2Fexkadbfail8okn4W80h7%2Fsso%2Fsaml%3FRelayState%3D%252Fhome%252Fadmin-entry

You then drop that insanity on the ACS of the loopback Identity Provider as the fromURI query parameter:

https://dev-971545.oktapreview.com/auth/saml20/loopback?fromURI=app%2Findependentconsultantdev927755_loopback_1%2Fexkadbfail8okn4W80h7%2Fsso%2Fsaml%3FRelayState%3D%252Fhome%252Fadmin-entry

You can convince yourself that worked or you can open the Network tab of your browser's developer tools and trace the communications. The ACS drops a RelayState prepending the slash (that's why we had to remove it), then gets redirected to the IdP (the loopback App), then gets reflected back to the ACS (preserving the RelayState). Login completes and Okta redirects to the loopback App SSO URL with the RelayState in the query parameter. Okta processes that and redirects to itself and then redirects to the embedded RelayState which takes you to the Admin Dashboard.

This is a working example of Deep Linking from SP-initiated flow from Okta with Okta as a SAML intermediary to another app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.