IDX21323 OpenIdConnectProtocolValidationContext.Nonce was null, OpenIdConnectProtocolValidatedIdToken.Payload.Nonce was not null
Asked Answered
T

15

23

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.

Telamon answered 20/4, 2018 at 14:33 Comment(0)
S
19

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 ;(

Stagg answered 3/8, 2020 at 18:47 Comment(2)
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.Ruyter
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.Muriate
L
15

How to solve IDX21323

The problem is solved with these lines of code. The reason for the error was that ASP.NET doesn't have the session info created yet. The function "authFailed.OwinContext.Authentication.Challenge()" fills the header with the info that it 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);
            }
        }
    });
Lyophobic answered 3/1, 2019 at 10:2 Comment(7)
Please add some explanation of how this code answers the question to improve your answer.Kookaburra
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.Simulacrum
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);Lesley
This is from Microsoft Docs, exactly what you are saying, maybe not a hack after all: learn.microsoft.com/en-us/answers/questions/137574/…Epicurus
@r3mark Please remove your comment that might mislead developers. This is an official solution: learn.microsoft.com/en-us/answers/questions/137574/….Aldine
Eeh dumb question but the await Task.FromResult(true); if it's not IDX21323 error, wont it still return true like it finished and the authentication went through? @Adrià Martínez LópezTwister
This doesn't work for me, adding it seems to cause a loop of retries which, after a while, just displays a message that I couldn't be signed.Bareback
K
10

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

Karole answered 24/10, 2018 at 11:14 Comment(1)
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 DattappaSusurration
V
10

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.

Vermeil answered 4/12, 2020 at 22:17 Comment(4)
I only set OpenIdConnectAuthenticationOptions.CookieManager = new SystemWebCookieManager(); and it workedKimble
this one works on my end too. thank you!Quar
This was a solution for me as well, but not alone. I also had to put this in web.config in <system.web>: <sessionState cookieSameSite="Lax" /> <httpCookies requireSSL="true" />Senlac
This is the correct answer, you only need the top one, however, if you're still having issues, you must be using https. http won't work. This stopped working because Chrome update 80 stopped accepting cookies from remote sites that don't have a SameSite attribute supplied. Searching for "SameSite=None IdentityServer4" will produce detailed discussions about this issue.Tripartite
A
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.

Adeleadelheid answered 11/5, 2018 at 18:5 Comment(1)
This package Kentor.OwinCookieSaver has been deprecated.Beene
S
4

Also check this link: https://learn.microsoft.com/en-us/aspnet/samesite/owin-samesite

For me it didn't work at first but the solution was to use https. I used Visual Studio IIS Express which hosts a website default using http. In test it worked because of https.

Stormi answered 24/8, 2020 at 7:14 Comment(0)
W
1

I've got the same error in production environment while locally it worked for all development team. I've tried Kentor.OwinCookieSaver solution suggested by Michael Flanagan but it did not help. After digging a little bit I discovered that authentication itself completed successfully and OwinContext contains user identity and claims, but AuthenticationFailed event handler is raised with IDX21323 exception. So I decided to use the following workaround - I updated AuthenticationFailed event handler:

// skip IDX21323 exception
if (context.Exception.Message.Contains("IDX21323"))
{
   context.SkipToNextMiddleware();
} else {
   context.HandleResponse();
   context.Response.Redirect("/Error?message=" + context.Exception.Message);
}
return Task.FromResult(0);

This way system will not throw IDX21323 exception but continues auth process and allows users to login and use the system.

I know this not a solution, but at least users can now login until I find a better way to solve this issue.

Wittgenstein answered 2/7, 2018 at 8:38 Comment(0)
F
1

My start and project URL's were different than the Redirect URI in Azure. I made all these match and no longer get IDX2132 error.

Fredrickafredrickson answered 22/5, 2019 at 17:4 Comment(0)
R
1

I needed to switch my local project to use HTTPS. I changed IISExpress to https:// and port to :443__ in the project settings.

Roccoroch answered 16/11, 2022 at 12:22 Comment(0)
U
0

Azure problems?

Make sure you are using the right domain name. I was debugging some firewall problems on Azure and I was using my-subdomain.azurewebsites.net to see if the site itself was up, and once it was, I forgot to change the domain name back to my-subdomain.mydomainname.org.

Ugly answered 4/6, 2020 at 13:15 Comment(0)
C
0

In my case, we were standing up new non-prod environments with very similar configs but one environment was throwing this error. It turned out that it was an issue with IIS configuration. After installing the HTTP Redirection role on the server and restarting, everything worked fine.

This can be configured by

  1. Opening up the Server Manager
  2. Click "Add roles and features" below "Configure this local server"
  3. Continue through setup pages to get to server roles. "Before You Begin" -> "Installation Type" -> "Server Selection" -> "Server Roles"
  4. Under Roles expand "Web Server (IIS)" -> "Web Server" -> "Common HTTP Features"
  5. Check "HTTP Redirection"
  6. Complete installation and restart server.

This is probably a niche answer as I'm guessing it's related to using URL rewrite/redirect rules specified in a web.config, but it took me forever to track down the issue. Hope it helps someone!

Coachwork answered 15/2, 2023 at 22:8 Comment(0)
S
0

I spent long hours looking for a fix for this bug. None of the previous answers work for me. Finally found this article:

https://devblogs.microsoft.com/dotnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/

This SameSite policy fix works for me (.Net MVC 4.8) in combination with Web.config:

</appSettings>
    ....
    <add key="aspnet:SuppressSameSiteNone" value="true" />
</appSettings>

...

<system.web>
    ...

    <authentication mode="None">
        <forms cookieSameSite="None" />
    </authentication>

    ... 

    <sessionState cookieSameSite="None" />
    <httpCookies requireSSL="true" />
</system.web>

Straggle answered 19/7, 2023 at 12:58 Comment(0)
B
0

This answer is specific to localhost environment. For me the fix was applying Self signed Certificate (IIS) to the web application and binding the https port of my application with this certificate.

Batt answered 22/9, 2023 at 14:23 Comment(0)
T
0

step1:

     app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
 {
     CookieManager = new SecureNonceCookieManager(new SystemWebCookieManager()),
...
}

step2:

public class SecureNonceCookieManager : ICookieManager
{
    private readonly ICookieManager _innerManager;

    public SecureNonceCookieManager() : this(new CookieManager())
    {
    }

    public SecureNonceCookieManager(ICookieManager innerManager)
    {
        _innerManager = innerManager;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value,
                                     CookieOptions options)
    {
        if(key.Contains("OpenIdConnect.nonce."))
        {
            options.Secure = true;
        }

        _innerManager.AppendResponseCookie(context, key, value, options);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        _innerManager.DeleteCookie(context, key, options);
    }

    public string GetRequestCookie(IOwinContext context, string key)
    {
        return _innerManager.GetRequestCookie(context, key);
    }

    
}
Tamanaha answered 29/2 at 9:14 Comment(0)
B
-1

In our case the problem is a wrong redirect after the identity provider POSTs the identity token + auth code to our app.

Our setup:

  • Azure app service
  • Azure Frontdoor configuration that hides the app's default URL (our-app.azurewebsites.net) behind our domain (our-app.our-domain.com)
  • OIDC Cookie auth

Flow:

  • user navigates to our-app.our-domain.com
  • redirect to login.microsoftonline.com (with nonce A)
  • after manual login: POST of id token (with nonce A) + auth code to our-app.our-domain.com
  • auth succeeds and our app (i.e. the framework) validates nonce A
  • redirect to our-app.azurewebsites.net (this is the issue)
  • redirect to login.microsoftonline.com (with new nonce B)
  • after (automatic) login: POST of id token (with nonce A) + auth code to our-app.our-domain.com
  • nonce validation fails; I assume because the auth context for our-app.our-domain.com doesn't have a nonce anymore and even if it did, it would be the wrong nonce anyway
  • authentication fails

Manual workaround:

  • user manually navigates to our-app.our-domain.com and auth succeeds due to already existing auth cookie .AspNet.Cookies

Automatic workaround:

  • catch IDX21323 auth failure and redirect to "/" (our-app.azurewebsites.net)
new OpenIdConnectAuthenticationOptions
{
    // ...
    Notifications = new OpenIdConnectAuthenticationNotifications()
    {
        // ...
        AuthenticationFailed = context =>
        {
            context.HandleResponse();

            if (context.Exception.Message.Contains("IDX21323"))
                context.Response.Redirect("/");
            else
                context.Response.Redirect("/AccessDenied");

            return Task.CompletedTask;
        }
    }
}

We're still investigating what causes the redirect to our-app.azurewebsites.net in order to really fix the issue and prevent leaking that URL to clients.

Burin answered 22/2 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.