Okta redirect dynamic relay state - saml

When using the Okta single sign-in with link redirect ( rather than send + generate a SAML request object ), is it possible to dynamically include the relay state? ( e.x. include a RelayState header or querystring )

Yes you can.
Assuming you are talking about this:
Retrieving a session cookie by visiting a session redirect link
The way I've done it is as follows:
appSSOUrl = 'https://your.okta.com/app/identifier/sso/saml'
RelayStateValue = URLENCODE(desired relay state here)
redirectUrl = URLENCODE(appSSOUrl + '?RelayState=' + RelayStateValue)
Sending the userAgent to
https://your.okta.com/login/sessionCookieRedirect?token={cookieToken}&redirectUrl={redirectUrl}
Here {redirectUrl} is a URL encoded version of your okta application SSO URL ? appended with a RelayState parameter. The Value of that parameter is the URL encoded relaystate you dynamically generated before the redirect.
The URL encoding may not be mandatory but i had good results doing it that way.
the resulting redirect URL is a doozy but it works.
https://your.okta.com/login/sessionCookieRedirect?token=00FAyayhEPQj3O7czF192BaEzjWhGjOSKk7f4QNRfe&redirectUrl=https%3A%2F%2Fyour.okta.com%2Fapp%2Fidentifier%2Fsso%2Fsaml%3FRelayState%3DParam1%253Dvalue1%2526param2%253Dvalue2%2526param3%253Dvalue3

By adding a querystring output to the redirect link
https://your.okta.com/.../sso/saml?RelayState=/param1/param2
the output Relay State will be sent in the return message body
{
SAMLResponse: ...,
RelayState: "/param1/param2"
}

Related

ServiceNow Redirect URL trimmed upto "&" character

My Web application redirects to a ServiceNow app and uses SSO to login. I want the user to be redirected to certain content on the ServiceNow platform.
Redirect URL: app?sys_kb_id=d34cecb01bdcd0102fsw&id=kb_article_view&sysparam_rank=1 &sysparam_tsqueryId=37ac2ea11b6689d4db49f2
The problem I am facing is that the redirect URL gets trimmed to the first parameter. This is because of the workflow that has been used and the usage of &.
The workflow we use in ServiceNow is as follows,
logout --> login with sso --> auth redirect
This workflow is important because the clients use the web application on shared hardware. To prevent cross-user access we logout the current user every time the ServiceNow application is opened.
Logout Request
https://example.service-now.com/logout.do?glide_sso_id=<sso-id>&logout_first=true&sysparm_goto_url=%2Flogin_with_sso.do%3Fglide_sso_id%3D<sso-id>%26login_redirect_uri%3Dapp%3Fsys_kb_id%3Dd34cecb01bdcb0102f09986a23shak90%26id%3Dkb_article_view%26sysparm_rank%3D1%26sysparm_tsqueryId%3D37ac2ea11b6689d4db49f2ff034jls72
Payload:{
sysparm_goto_url=%2Flogin_with_sso.do%3Fglide_sso_id%3D<sso-id>%26login_redirect_uri%3Dmyhr%3Fsys_kb_id%3Dd34cecb01bdcb0102f09986a23shak90%26id%3Dkb_article_view%26sysparm_rank%3D1%26sysparm_tsqueryId%3D37ac2ea11b6689d4db49f2ff034jls72
}
Login Request
https://example.service-now.com/login_with_sso.do?glide_sso_id=<sso-id>&login_redirect_uri=app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90&id=kb_article_view&sysparm_rank=1&sysparm_tsqueryId=37ac2ea11b6689d4db49f2ff034jls72
Payload: {
login_redirect_uri=app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90&id=kb_article_view&sysparm_rank=1&sysparm_tsqueryId=37ac2ea11b6689d4db49f2ff034jls72
}
The login API parses the redirect URL, this causes the encoded URL characters to be decoded.
Because of the "&" character in the redirect URL, the URL breaks into separate query parameters,
requiredRedirectUrl: app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90&id=kb_article_view&sysparm_rank=1&sysparm_tsqueryId=37ac2ea11b6689d4db49f2ff034jls72
actualRedirectUrl: app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90
++ id=kb_article_view
++ sysparm_rank=1
++ sysparm_tsqueryId=37ac2ea11b6689d4db49f2ff034jls72
Because the redirect URL is incomplete, the user comes to the landing page and not to the content page.
RequiredEndUrl: https://example.service-now.com/app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90&id=kb_article_view&sysparm_rank=1&sysparm_tsqueryId=37ac2ea11b6689d4db49f2ff034jls72
ActualEndUrl: https://example.service-now.com/app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90
Is there any way to ensure that the Redirect URL is not decoded by the Login API?
Or is there another method to achieve the requirement.
I found a fix for this. The issue was that the logout API decodes the redirect URL before calling the login API, this causes an issue because the characters like "&" are not escaped.
I encoded the redirect URL twice (Double Encode URL) and then added it to the logout request. With this when URL is decoded initially the characters still remain escaped, and the actual redirect URL is sent to the last API call.
Redirect URL: app?sys_kb_id=d34cecb01bdcb0102f09986a23shak90&id=kb_article_view&sysparm_rank=1&sysparm_tsqueryId=37ac2ea11b6689d4db49f2ff034jls72
Double Encoded URL: app%253Fsys_kb_id%253Dd34cecb01bdcb0102f09986a23shak90%2526id%253Dkb_article_view%2526sysparm_rank%253D1%2526sysparm_tsqueryId%253D37ac2ea11b6689d4db49f2ff034jls72

"Redirect URI does not match registered redirect URI" when link has query id 'https://someurl/organisation/50'

Basically when i add 'https://someurl/organisation/' to Valid redirect URIs it doesn't work as intended because url contains id in the end. How i should form valid url for developer console for this case?
You can put that id parameter as query param rather than path param.
Alternatively, to get the id param in your auth callback handler - you can use state param of OAuth2 to pass that info.
In that case - you can still host the handler on https://someurl/organisation/ - have it registered on the developer console. And pass the id: 50 as state param which you will get back in the redirect from Instagram.

Get location fragment with Fetch API redirect response

I am trying to get the redirect response location fragment of a fetch API request. But I can't figure how to access it, if possible.
The context is that I am doing an OpenID Connect request in implicit flow, for a WebRTC Identity Proxy assertion generation.
OIDC specs define the answer of the request as:
When using the Implicit Flow, all response parameters are added to the
fragment component of the Redirection URI
HTTP/1.1 302 Found
Location: https://client.example.org/cb#
access_token=SlAV32hkKG
...
So I'm making the request with fetch set in manual mode. But the response is then an opaque-redirect filtered response, which hides the location header. (https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect)
Other mode for fetch are error and follow which would not help. While XHR automatically follows the redirect so would not help either. I may be missing something from the fetch API, but it seems to be something hidden on purpose.
Could someone gives me a way to access this information (or a confirmation it's impossible) ?
Is there any alternative to fetch and XHR to make this request, which would allow to access the redirect location header?
Since XHR automatically / opaquely follows redirects (in the event you're using the whatwg-fetch polyfill for example), one possible solution is to check the response.url of the fetch resolution, to see if it matches a redirect location that you expect.
This only helps if the possible redirect locations are limited or match some pattern --- for instance, if you could expect at any time to be redirect to /login:
function fetchMiddleware(response) {
const a = document.createElement('a');
a.href = response.url;
if (a.pathname === '/login') {
// ...
} else {
return response;
}
}
fetch(`/api`)
.then(fetchMiddleware)
.then(function (response) {
// ...
});
fetch isn't able to polyfill the entire standard. Some notable differences include:
Inability to set the redirect mode.
See David Graham comment on the Disable follow redirect:
This is a nice addition to the Fetch API, but we won't be able to polyfill it with XMLHttpRequest. The browser navigates all redirects before returning a result, so there is no opportunity to interrupt the redirect flow.
My Solution:
1). First solution: we are sending 200 status and redirect url(in the http header) from the server and client is redirecting based on that.
2). Second solution: Server could also redirect to with 301 and redirect url. I think, This is the best solution(i.e if we consider SEO).

SoundCloud API: redirect url

Consider this example for authentication from PHP at https://developers.soundcloud.com/docs/api/guide#authentication seem to suggest you can pass a redirect url as a parameter when you flow a user throught the authentication process:
require_once 'Services/Soundcloud.php';
// create client object with app credentials
$client = new Services_Soundcloud(
'CLIENT_ID', 'CLIENT_SECRET', 'REDIRECT_URL');
// redirect user to authorize URL
header("Location: " . $client->getAuthorizeUrl());
Note the 'REDIRECT_URL' argument in the call to the constructor.
That seems to suggest I can pass an arbitrary redirect url as a parameter, just like you can do with Twitter (the API is quite similar).
However, if I pass an url that does not match the unique redirect url configured for the application, I get an error when the user is redirected to my url:
error=redirect_uri_mismatch&error_description=The+redirection+URI+provided+does+not+match+a+pre-registered+value.
So, what is that parameter supposed to be for, if the only valid value is the redirect url configured for the application?
And how are you supposed to handle authentication if the user can only be redirected to a single fixed url after authentication?? That makes the API completely unusable. When you have a user login into any API (e.g. Twitter or Facebook), you need them to be returned to the page from which they clicked the link to log in, and it is a ridiculous restriction that that url be unique. No other social network api that I've ever seen has this restriction.
Is SoundCloud API really so flawed or am I missing something?
I got an answer from Glen Scott, the author of the php-soundcloud library (a pretty decent wrapper around this terrible API) who provides a workaround. It's painful as it involves an additional redirect but it's all the API allows.
https://github.com/mptre/php-soundcloud/issues/36
I quote:
The API does not allow an arbitrary URL. As you noted, this is unlike
most other oAuth-backed social network API's. The workaround I can
recommend is using the state parameter to pass back your return URL.
You can do this when generating the authorization URL like this:
$client->getAuthorizeUrl(
array(
'state' => 'http://example.com/return'
) You'll get the state parameter added to the static redirect URL. For example, if you set your redirect URL to
http://example.com/callback then SoundCloud will redirect an
authenticated user to
http://example.com/callback?state=http://example.com/return
Your callback script will need to look for the state GET parameter,
and redirect using it.

Re-post HTML form after OpenAM/OpenSSO authentication

The default process when authenticating user on OpenAM/OpenSSO works with a 302 http redirection, opening OpenAM/OpenSSO authentication formular. The original URL is stored into "goto" parameter, which allows OpenAM/OpenSSO to redirect the user back on orignal URL after correct authentication.
This works well when using HTTP GET method (i.e. when entering URL), but it is not suitable for POST method. For instance, if the session expires while the user posts a HTML form, the data are lost because HTML form inputs are not present in goto parameter.
Do you know it it is possible to configure J2EE Agent in order it re-posts user HTML form after valid authentication ?
Both the Java EE and the Web agents support post data preservation, see the documentation.