IDX21323 OpenIdConnectProtocolValidationContext.Nonce was null, OpenIdConnectProtocolValidatedIdToken.Payload.Nonce was not null

36,570

Solution 1

In my case, this was a very weird problem because it didn't happen in for everyone, only few clients and devs have this problem.

If you are having this problem in chrome only (or a browser that have the same engine) you could try setting this flag on chrome to disabled.

enter image description here

What happens here is that chrome have this different security rule that " If a cookie without SameSite restrictions is set without the Secure attribute, it will be rejected". So you can disable this rule and it will work.

OR, you can set the Secure attribute too, but I don't know how to do that ;(

Solution 2

How to solve IDX21323

The problem is solved with this lines of codes, the reason of the error was that ASP.NET don't has the sessión info created yet. The function "authFailed.OwinContext.Authentication.Challenge()" fill the header with the info that needs for the authentication.


        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
    {
        Notifications = new OpenIdConnectAuthenticationNotifications()
        {
            AuthenticationFailed = AuthenticationFailedNotification<OpenIdConnect.OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> authFailed =>
            {
                if (authFailed.Exception.Message.Contains("IDX21323"))
                {
                    authFailed.HandleResponse();
                    authFailed.OwinContext.Authentication.Challenge();
                }

                await Task.FromResult(true);
            }
        }
    });

Solution 3

Check the URL mentioned in the AD App Registrations --> Settings --> Reply URL's. if for example that url is https://localhost:44348/

Go to MVC Project --> Properties (Right Click and Properties) --> Web Section --> Start URL and Project URL should also be https://localhost:44348/

This has resolved the issue for me. other option is to dynamically set the Redirect URL after AD authentication in Startup.Auth

Solution 4

See System.Web response cookie integration issues by Chris Ross (AKA Tratcher on github). The OWIN cookie manager and the original cookie management built into ASP.NET Framework can clash in an unhelpful way, and there is no universal solution to this. However, in setting up OIDC authentication I found this suggested work-around from that link worked for me:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
   // ...
   CookieManager = new SystemWebCookieManager()
});

And:

OpenIdConnectAuthenticationOptions.CookieManager = new SystemWebCookieManager();

This causes OWIN to use the ASP.NET Framework cookie jar/store and avoid the clash. I imagine there will be side effects to his, so tread carefully! Read the link for a full explanation.

Solution 5

With it being inconsistent, it makes me believe the error you are seeing is caused by what people call "Katana bug #197".

Luckily, there is a workaround with a nuget package called Kentor.OwinCookieSaver.

After installing the nuget package add app.UseKentorOwinCookieSaver(); before app.UseCookieAuthentication(cookieOptions);.

For more info, checkout the Kentor.OwinCookieSaver repo on GitHub.

Share:
36,570

Related videos on Youtube

Michael Flanagan
Author by

Michael Flanagan

Updated on July 09, 2022

Comments

  • Michael Flanagan
    Michael Flanagan almost 2 years

    I'm attempting to authenticate for Azure AD and Graph for an Intranet (Based off Orchard CMS), this functions as expected on my local machine, however, when accessing what will be the production site (already set up with ssl on our internal dns), I get the above error at times, it's relatively inconsistent, others in my department while accessing usually get this error.

    My Authentication Controller is as follows:

    public void LogOn()
        {
            if (!Request.IsAuthenticated)
            {
    
                // Signal OWIN to send an authorization request to Azure.
                HttpContext.GetOwinContext().Authentication.Challenge(
                  new AuthenticationProperties { RedirectUri = "/" },
                  OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }
        }
    
        public void LogOff()
        {
            if (Request.IsAuthenticated)
            {
                ClaimsPrincipal _currentUser = (System.Web.HttpContext.Current.User as ClaimsPrincipal);
    
                // Get the user's token cache and clear it.
                string userObjectId = _currentUser.Claims.First(x => x.Type.Equals(ClaimTypes.NameIdentifier)).Value;
    
                SessionTokenCache tokenCache = new SessionTokenCache(userObjectId, HttpContext);
                HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
            }
    
            SDKHelper.SignOutClient();
    
            HttpContext.GetOwinContext().Authentication.SignOut(
              OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
        }
    

    My openid options are configured as follows:

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
    
            var openIdOptions = new OpenIdConnectAuthenticationOptions
            {
                ClientId = Settings.ClientId,
                Authority = "https://login.microsoftonline.com/common/v2.0",
                PostLogoutRedirectUri = Settings.LogoutRedirectUri,
                RedirectUri = Settings.LogoutRedirectUri,
                Scope = "openid email profile offline_access " + Settings.Scopes,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                },
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthorizationCodeReceived = async (context) =>
                    {
                        var claim = ClaimsPrincipal.Current;
                        var code = context.Code;                        
    
                        string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
    
    
                        TokenCache userTokenCache = new SessionTokenCache(signedInUserID,
                            context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
                        ConfidentialClientApplication cca = new ConfidentialClientApplication(
                            Settings.ClientId,
                            Settings.LogoutRedirectUri,
                            new ClientCredential(Settings.AppKey),
                            userTokenCache,
                            null);
    
    
                        AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, Settings.SplitScopes.ToArray());
                    },
                    AuthenticationFailed = (context) =>
                    {
                        context.HandleResponse();
                        context.Response.Redirect("/Error?message=" + context.Exception.Message);
                        return Task.FromResult(0);
                    }
                }
                };
    
            var cookieOptions = new CookieAuthenticationOptions();
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseCookieAuthentication(cookieOptions);
    
            app.UseOpenIdConnectAuthentication(openIdOptions);
    

    The url for redirection is kept consistent both at apps.dev.microsoft.com and in our localized web config.

  • Eric Hauenstein
    Eric Hauenstein over 5 years
    Please add some explanation of how this code answers the question to improve your answer.
  • m.t.bennett
    m.t.bennett almost 5 years
    This resolved the issue for me; I had been testing locally on the server through localhost:8080, however I had previously setup the reply URLs as an actual domain name, and without the localhost:8080. When testing I was using the localhost URL - which was causing this error. Thanks @Narasimha Rao Dattappa
  • r3mark
    r3mark almost 5 years
    This is not a solution but a hack
  • jhhwilliams
    jhhwilliams over 4 years
    In my case the cause was clicking the browser's back button after login. This causes the cached NONCE to be used which then results in the IDX21323 error. Simply issuing another OwinContext.Authentication.Challenge() which will create a 'fresh' NONCE doesn't seem like that much of a hack to me.
  • mavi
    mavi about 4 years
    I had to add some lines in order to work and let me login again. context.HandleResponse(); var url = context.Request.Uri.ToString(); context.OwinContext.Response.Redirect(url);
  • Greg
    Greg over 3 years
    Not sure what happened in the last 7 days, everything was working fine locally then today, it doesn't. I disabled this same flag, and now everything works.
  • Ries Vriend
    Ries Vriend over 3 years
    This fixed error IDX21323 for me. Root cause: The Microsoft code samples use https (port 443), my own project uses http (port 80). To prevent having to change the Chrome flag, your dev web server needs to accessed over https.
  • M Moore
    M Moore over 3 years
    This is from Microsoft Docs, exactly what you are saying, maybe not a hack after all: docs.microsoft.com/en-us/answers/questions/137574/…
  • ppenchev
    ppenchev about 3 years
    This package Kentor.OwinCookieSaver has been deprecated.
  • KanisXXX
    KanisXXX over 2 years
    I only set OpenIdConnectAuthenticationOptions.CookieManager = new SystemWebCookieManager(); and it worked
  • aronccs
    aronccs about 2 years
    this one works on my end too. thank you!
  • Exegesis
    Exegesis almost 2 years
    @r3mark Please remove your comment that might mislead developers. This is an official solution: docs.microsoft.com/en-us/answers/questions/137574/….