Reputation: 21686
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)?
?RelayState=hello
after itHow do I hand RelayState correctly to Okta-side ACS URLs so that it gets to the IdP as entered?
Upvotes: 1
Views: 5379
Reputation: 36
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
Upvotes: 2
Reputation: 21686
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:
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.
Upvotes: 0