Sustainsys / Saml2

Saml2 Authentication services for ASP.NET
Other
959 stars 602 forks source link

Acs method fails on Chinese OS/browser #1338

Closed ghost closed 2 years ago

ghost commented 2 years ago

OS: Windows 10 Professional 20H2 (19042.1387) 64-bit Browser: Chrome 99.0.4844.51 .NET Installed: v4.8 App Uses: .NET Framework: v4.8 Asp.Net MVC: v5.2.7 Sustainsys: NuGet v2.9.0

I have deployed my application on a Chinese Windows 10 machine using Chrome v99 set to use Chinese language. When I configure my app to use SAML2 and our organization's Identity Provider, I get the exception indicated below. This IDP has been used successfully with the same code in English and German.

IDX10223: Lifetime validation failed. The token is expired. ValidTo: 'System.DateTime', Current time: 'System.DateTime'.

Call Stack: [SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo: 'System.DateTime', Current time: 'System.DateTime'.] Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable1 notBefore, Nullable1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) +1546 Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateLifetime(Nullable1 notBefore, Nullable1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters) +23 Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateConditions(Saml2SecurityToken samlToken, TokenValidationParameters validationParameters) +195 Sustainsys.Saml2.Saml2P.Saml2PSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) +57 Sustainsys.Saml2.Saml2P.d66.MoveNext() +731 System.Collections.Generic.List1..ctor(IEnumerable1 collection) +453 System.Linq.Enumerable.ToList(IEnumerable1 source) +73 Sustainsys.Saml2.Saml2P.Saml2Response.GetClaims(IOptions options, IDictionary2 relayData) +242 Sustainsys.Saml2.WebSso.AcsCommand.ProcessResponse(IOptions options, Saml2Response samlResponse, StoredRequestState storedRequestState, IdentityProvider identityProvider, String relayState) +87 Sustainsys.Saml2.WebSso.AcsCommand.Run(HttpRequestData request, IOptions options) +968 orx.Controllers.AuthenticationController.Acs() +120 lambda_method(Closure , ControllerBase , Object[] ) +87 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +35 System.Web.Mvc.Async.<>c.<BeginInvokeSynchronousActionMethod>b__9_0(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39 System.Web.Mvc.Async.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) +77 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.<>cDisplayClass11_0.b0() +80 System.Web.Mvc.Async.<>cDisplayClass11_2.b2() +396 System.Web.Mvc.Async.<>cDisplayClass11_2.b2() +396 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42 System.Web.Mvc.Async.<>cDisplayClass3_6.b4() +50 System.Web.Mvc.Async.<>cDisplayClass3_1.b1(IAsyncResult asyncResult) +188 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38 System.Web.Mvc.<>c.b152_1(IAsyncResult asyncResult, ExecuteCoreState innerState) +29 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +73 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +52 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +39 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38 System.Web.Mvc.<>c.b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState) +43 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +73 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +431 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +75 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +158

Screen captures of the browser and the cookie contents are attached.

SAML2-ZH-Cookie SAML2-ZH-Browser

This is the Acs() method in our application:

    public ActionResult Acs()
    {
        var result = CommandFactory.GetCommand(CommandFactory.AcsCommandName).Run(Request.ToHttpRequestData(), _options);

        if (result.HandledResult)
            throw new NotSupportedException("The controller doesn't support setting CommandResult.HandledResult.");

        result.SignInOrOutSessionAuthenticationModule();
        result.ApplyCookies(Response, _options.Notifications.EmitSameSiteNone(Request.UserAgent));

        return result.ToActionResult();
    }
ghost commented 2 years ago

Well, the web.config settings didn't get added correctly in the original post. Let's try that again:

  <configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <section name="sustainsys.saml2" type="Sustainsys.Saml2.Configuration.SustainsysSaml2Section, Sustainsys.Saml2" />
  </configSections>

  <sustainsys.saml2 entityId="https://localhost:44359/Authentication/Metadata" returnUrl="https://localhost:44359/" modulePath="/Authentication" authenticateRequestSigningBehavior="IfIdpWantAuthnRequestsSigned">
    <nameIdPolicy allowCreate="true" format="Persistent" />
    <requestedAuthnContext classRef="Password" comparison="Exact"/>
    <identityProviders>
      <add entityId="https://xxx.xxxxxxx.xxx/0f634ac8-b39f-41b6-83ba-8f157876c692/" signOnUrl="https://xxx.xxxxxxx.xxx/0f634ac8-b39f-41b6-83ba-8f157876c692/saml2" allowUnsolicitedAuthnResponse="true" binding="HttpRedirect">
        <signingCertificate fileName="~/Saml2/certificate.cer"/>
      </add>
    </identityProviders>
  </sustainsys.saml2>

I have also tested on Japanese OS/browser with no issues.

ghost commented 2 years ago

Also tested on Russian OS/browser with no issues.

AndersAbel commented 2 years ago

Can you please use Saml2 dev tools in the browser to check the token lifetime of the request? I'm sorry that the log message is incorrect and echoes the type instead of the actual value.

ghost commented 2 years ago

I'm sorry, I was out of the office for a few days. I am no longer able to reproduce the error. Everything seems to be working now. That must have been a random glitch on my system.