ComponentSpace

Forums



SamlAuthenticationHandler Challenge redirectUri


SamlAuthenticationHandler Challenge redirectUri

Author
Message
jasonquanumworkplace
jasonquanumworkplace
New Member
New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)New Member (10 reputation)

Group: Forum Members
Posts: 7, Visits: 39
Hello,

I am in the process of implementing SAML auth with Identity Server 4 as a Service Provider.  I have everything setup and working properly except for the handling of the External Login callback after authenticating with and external idp.

It seems no matter what I pass in the AuthenticationProperties object that is passed to the ChallengeResult, after I successfully login with the Idp I am always redirected to the default callback url which is: /Identity/Account/ExternalLogin?handler=Callback.

Here is my code for setting up the AuthenticationProperties and ChallengeResult:   

   var props = new AuthenticationProperties()
    {
      RedirectUri = Url.Action("ExternalLoginCallback"),
      Items =
      {
       { "returnUrl", returnUrl },
       { "scheme", provider }
      }
    };
    return new ChallengeResult(provider, props);


based on that code I see the following in the HandleChallengeAsync method of the SamlAuthenticationHandler for the AuthenticationProperties object:
Items: 
{[.redirect, /account/ExternalLoginCallback]}
{[returnUrl, /connect/authorize/callback....}
{[scheme, saml2-okta-idsrv]}

And the redirectUri is "/account/ExternalLoginCallback".

Not only am I not getting redirected back to the right callback url, but the Items I provided in the authentication properties (scheme and returnUrl) are not available either.

When I put in a route for the default callback url I am able to inspect the authentication result with this code:

var result = await HttpContext.AuthenticateAsync(_appConfiguration.Value.ExternalCookieAuthenticationSchemeEnvironment)


That result comes back with Succeeded = true and I see that the claims from the principal are correct.  But the result properties has the following:
redirectUri = /Identity/Account/ExternalLogin?handler=Callback
Properties.Items:
{[LoginProvider, saml2-okta-idsrv]}
{[.redirect, /Identity/Account/ExternalLogin?handler=Callback]}
{[.issued, Thu, 06 Dec 2018 00:03:46 GMT]}
{[.expires, Thu, 20 Dec 2018 00:03:46 GMT]}

Shouldnt the authentication properties include the proper redirect and the extra items I provided when passed into the ChallengeResult?

Here is my code where I am setting up the saml provider

builder.AddSaml(externalIdentityProviderModel.AuthenticationScheme,
  externalIdentityProviderModel.DisplayName ?? "",
  options =>
  {
   options.SignInScheme = configurationOptions.Value.ExternalCookieAuthenticationSchemeEnvironment;
   options.PartnerName = () => externalIdentityProviderModel.SamlConfig.Name;
  });


I know that I can provide a LoginCompletionUrl setting in the options as well, and while that does override the default url and redirect me to where I want to go, it still does not have the extra Items that I provided in the AuthenticationProperties (returnUrl, and scheme).

In my search for answers I also came across this forum post that seems to be the same issue as I am having, if it helps any.
https://www.componentspace.com/Forums/9181/RelayState-is-overwritten-by-SamlAuthenticationHandler

Can you tell me if this is a bug or if I am doing something wrong.

Let me know if you need any other information from me.

Thanks
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Once SSO completes, the SAML authentication handler will redirect to the URL specified by AuthenticationProperties.RedirectUri.
So in this case it should redirect to /account/ExternalLoginCallback.
Please enable SAML trace and send the generated log file as an email attachment to [email protected] mentioning your forum post.
https://www.componentspace.com/Forums/7936/Enabling-SAML-Trace



Regards
ComponentSpace Development
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Thanks for the log.
We use a SAML session cookie to keep track of state associated with SAML SSO.
Two separate sub-domains were being used and the SAML session cookie wasn't being presented and so the session state was effectively lost.
Specifying a Domain in the DistributedSsoSessionStoreOptions.CookieOptions resolved the issue.

Regards
ComponentSpace Development
Wouter van de Weerd
Wouter van de Weerd
New Member
New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)

Group: Forum Members
Posts: 9, Visits: 55
I seem to be having the same problem.
Our setup is as follows:
SP-initiated login, using an OpenIdConnect test client, an IdentityServer4 IdP, which in it's turn connects using SAML to an external IdP.
The test client and the IdP runs on the same domain, but on different sub domains. The external IdP is -of course- a completely different domain.

OpenIdConnect test client: https://testclient.dev.mydomain.nl
IdP: https://auth.dev.mydomain.nl
External IdP: https://dummy-auth.dev.myExternalIdPdomain.nl

After the succesful login in the external IdP, a post is done to https://auth.dev.mydomain.nl/SAML/AssertionConsumerService.
But then there is always a redirect to "/Identity/Account/ExternalLogin?handler=Callback" .

However, because we don't want to use the "Identity" part in the path, I have configured in the Startup class:

services.Configure<DistributedSsoSessionStoreOptions>(options =>
   {
       options.CookieOptions = new ComponentSpace.Saml2.Bindings.CookieOptions()
       {
           Domain = "mydomain.nl"
       };
   });

And:

services.AddAuthentication().AddSaml(options =>
    options.LoginCompletionUrl = relayState => !string.IsNullOrEmpty(relayState)
        ? QueryHelpers.AddQueryString("/Account/ExternalLogin?handler=Callback", "ReturnUrl", relayState)
       : "/Account/ExternalLogin?handler=Callback";


Is the specified domain correct? Or should it be: "dev.mydomain.nl" ?
Or could there be another reason why the configured LoginCompletionUrl is not used?


Wouter van de Weerd
Wouter van de Weerd
New Member
New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)

Group: Forum Members
Posts: 9, Visits: 55
WoutervdW - 8/19/2019
I seem to be having the same problem.
Our setup is as follows:
SP-initiated login, using an OpenIdConnect test client, an IdentityServer4 IdP, which in it's turn connects using SAML to an external IdP.
The test client and the IdP runs on the same domain, but on different sub domains. The external IdP is -of course- a completely different domain.

OpenIdConnect test client: https://testclient.dev.mydomain.nl
IdP: https://auth.dev.mydomain.nl
External IdP: https://dummy-auth.dev.myExternalIdPdomain.nl

After the succesful login in the external IdP, a post is done to https://auth.dev.mydomain.nl/SAML/AssertionConsumerService.
But then there is always a redirect to "/Identity/Account/ExternalLogin?handler=Callback" .

However, because we don't want to use the "Identity" part in the path, I have configured in the Startup class:

services.Configure<DistributedSsoSessionStoreOptions>(options =>
   {
       options.CookieOptions = new ComponentSpace.Saml2.Bindings.CookieOptions()
       {
           Domain = "mydomain.nl"
       };
   });

And:

services.AddAuthentication().AddSaml(options =>
    options.LoginCompletionUrl = relayState => !string.IsNullOrEmpty(relayState)
        ? QueryHelpers.AddQueryString("/Account/ExternalLogin?handler=Callback", "ReturnUrl", relayState)
       : "/Account/ExternalLogin?handler=Callback";


Is the specified domain correct? Or should it be: "dev.mydomain.nl" ?
Or could there be another reason why the configured LoginCompletionUrl is not used?


Mmm, I just saw that the "saml-session" cookie was set with a property "same-site=lax".

So I added a CookiePolicy in my Startup of my IdP:

app.UseCookiePolicy(new CookiePolicyOptions
{
  HttpOnly = HttpOnlyPolicy.Always,
  Secure = CookieSecurePolicy.Always,
  MinimumSameSitePolicy = SameSiteMode.None
});


This solved my problem, now the redirect is going to "/External/Callback".

But is this the correct solution?
Or am I now creating a security risk?


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
You shouldn't have to set the domain property of the cookie. My understanding of your configuration is that the cookie isn't being shared across sub-domains etc. It only applies to the IdentityServer4 server where the SAML code is running. By default we don't specify a domain and this should work in most scenarios.

We default the SameSite flag to None. I'm not sure why you're seeing SameSite=lax although it can be changed through the DistributedSsoSessionStoreOptions.

What might be a good idea is to revert the code so the cookie settings are back to their defaults and the issue occurs. Using the browser developer tools, record the network traffic for the SSO, save it as an HAR file and send this to [email protected] mentioning your forum post. We can take a look at the flow and what's happening with the cookie.

Regards
ComponentSpace Development
Wouter van de Weerd
Wouter van de Weerd
New Member
New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)

Group: Forum Members
Posts: 9, Visits: 55
ComponentSpace - 8/19/2019
You shouldn't have to set the domain property of the cookie. My understanding of your configuration is that the cookie isn't being shared across sub-domains etc. It only applies to the IdentityServer4 server where the SAML code is running. By default we don't specify a domain and this should work in most scenarios.

We default the SameSite flag to None. I'm not sure why you're seeing SameSite=lax although it can be changed through the DistributedSsoSessionStoreOptions.

What might be a good idea is to revert the code so the cookie settings are back to their defaults and the issue occurs. Using the browser developer tools, record the network traffic for the SSO, save it as an HAR file and send this to [email protected] mentioning your forum post. We can take a look at the flow and what's happening with the cookie.

If I don't set the domain property indeed everything still works fine.
But not setting the "MinimumSameSitePolicy = SameSiteMode.None" results in the error.

So I have just send the har- and logfiles like you suggested.
I am looking forward to seeing your findings.


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Perhaps the UseCookiePolicy is overriding our configuration. I'll need to investigate this. It's still not clear to me why you're seeing SameSite=lax as we default to None in our code.

I'm afraid we haven't received an email from you. Please zip up these files and try again. Perhaps also send a separate email with no attachments to let us know.

Regards
ComponentSpace Development
Wouter van de Weerd
Wouter van de Weerd
New Member
New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)

Group: Forum Members
Posts: 9, Visits: 55
For everybody who is following/reading this thread:

After succesfully sending the files and the analysis by ComponentSpace the suggested solution was to indeed add in Startup:

app.UseCookiePolicy(new CookiePolicyOptions
{
  MinimumSameSitePolicy = SameSiteMode.None
});


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)ComponentSpace Development (4.4K reputation)

Group: Administrators
Posts: 3.2K, Visits: 11K
Thanks Wouter. I'm still not sure why this is required and will investigate further. I will report my findings here for everyone's benefit.

Regards
ComponentSpace Development
GO


Similar Topics


Execution: 0.000. 2 queries. Compression Enabled.
Login
Existing Account
Email Address:


Password:


Select a Forum....












Forums, Documentation & Knowledge Base - ComponentSpace


Search