Closed qudooschaudhry closed 3 weeks ago
I think RelayState is the concept you are looking for: https://stackoverflow.com/q/34350160/151212
https://developer.okta.com/docs/concepts/saml/#understand-sp-initiated-sign-in-flow
Thanks!
Is it just passed as a QueryString?
I updated my redirect to
return RedirectToAction("SignIn", "Saml2", new {idp=idPEntityId, RelayState=ssoRequestId})
In the network tab, I see the relaystate parameter being sent to OKTA. However, it is not coming back. I wonder if I need to enable something in OKTA admin to pass it back.
OK, I see that the relaystate parameter is being posted back along side the SAML response the /acs endpoint. However after that I am not sure what the /acs endpoint does with it? How do I retrieve it, I see it nowhere in cookies or any other information when acs redirects to my url.
@AndersAbel I have looked at the SAML2 code for the v2 branch and I think I spot an issue in the AcsCommand.
In the controller at the /acs end point It calls result.ApplyCookies which in turn looks for this
if (!string.IsNullOrEmpty(commandResult.SetCookieName))
However, I do not see the SetCookieName being set anywhere in the AcsCommand. I believe this in turn does not create the relay state cookie.
Do you think this is an issue? I can create a PR if you think it's an issue.
Perhaps this is by design as I see it sets another cookie instead
result.ClearCookieName = StoredRequestState.CookieNameBase + unbindResult.RelayState;
and anything in the ClearCookieName is being expired in the ApplyCookies method.
if the value that my application passed to the IDP gets passed to IDP as relaystate but then it gets cleared on the /acs end point, how am I supposed to retrieve it back?
ok digging further into this it seems that I need relayStateUsedAsReturnUrl="true" on my config setting. I tried this and was expecting that perhaps it gets appended as a relayState query string to my return url, however that did not happen either. Again looking at the AcsCommand --> GetLocation, it seems that if there is a storedRequestState, then it will not do anything with the relayStateUsedAsReturnUrl setting.
if (storedRequestState != null)
{
return storedRequestState.ReturnUrl ?? options.SPOptions.ReturnUrl;
}
else
{ //When IDP-Initiated
if (identityProvider.RelayStateUsedAsReturnUrl && !string.IsNullOrWhiteSpace(relayState))
{
if (!PathHelper.IsLocalWebUrl(relayState))
{
if (!options.Notifications.ValidateAbsoluteReturnUrl(relayState))
{
throw new InvalidOperationException("Return Url must be a relative Url.");
}
}
return new Uri(relayState, UriKind.RelativeOrAbsolute);
}
}
return options.SPOptions.ReturnUrl;
When using the MVC package you would have to implement the AcsCommandResultCreated
notification to retrieve the state. The SessionAuthenticationModule
used by the MVC package doesn't support persisting the additional state to the session cookie.
I added the notification
.AcsCommandResultCreated = (commandResult, response) =>
{
var relayState = commandResult.RelayState;
};
it does hit this when I come back to /acs however, commandresult.RelayState is empty.
It's been a long time since I wrote or used the Mvc package, so I went back and read up on the code.
The short answer is that custom relaystate is not supported with the Mvc package. The relaystate you see being used is created for internal book-keeping. For Mvc applications you can use the Own package instead.
Another option is to create your own SignIn implementation based on the existing one in https://github.com/Sustainsys/Saml2/blob/3508193a1919d7fdefec5c5da319f4658f3f7d0d/Sustainsys.Saml2.Mvc/Saml2Controller.cs#L43. The command object returned from the CommandFactory is a SignInCommand. If you cast it to that, you can access another overload of the Run
method that allows you to add custom relaystate. That would then be available in AcsCommandResultCreated
I have inherited some code that uses Sustainsys.Saml2.Mvc 2.92 to redirect to OKTA for login. I need to pass an Id before going to OKTA and need to retrieve this Id after a successful login. I have been trying to find out how to do this but cannot find a definitive answer. Any way I can achieve this?
Thanks!