19

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.

Brett Caswell
  • 1,486
  • 1
  • 13
  • 25
Michael Flanagan
  • 315
  • 1
  • 3
  • 7

12 Answers12

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

Vencovsky
  • 28,550
  • 17
  • 109
  • 176
  • 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. – Greg Aug 18 '20 at 06:43
  • 9
    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. – Ries Vriend Aug 22 '20 at 05:35
14

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);
            }
        }
    });
  • 3
    Please add some explanation of how this code answers the question to improve your answer. – Eric Hauenstein Jan 03 '19 at 14:19
  • 4
    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. – jhhwilliams Nov 20 '19 at 02:42
  • 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); – mavi Apr 28 '20 at 16:59
  • 3
    This is from Microsoft Docs, exactly what you are saying, maybe not a hack after all: https://learn.microsoft.com/en-us/answers/questions/137574/azure-active-directory-authentication-error-owin.html – M Moore Jan 14 '21 at 13:51
  • @r3mark Please remove your comment that might mislead developers. This is an official solution: https://learn.microsoft.com/en-us/answers/questions/137574/azure-active-directory-authentication-error-owin.html. – Exegesis Jun 24 '22 at 13:29
  • 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ópez – Tobbin2 Sep 19 '22 at 09:27
  • 1
    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. – dzenesiz Feb 23 '23 at 10:58
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

  • 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 – m.t.bennett Jul 10 '19 at 00:34
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.

redcalx
  • 8,177
  • 4
  • 56
  • 105
  • I only set `OpenIdConnectAuthenticationOptions.CookieManager = new SystemWebCookieManager();` and it worked – KanisXXX Jan 10 '22 at 13:28
  • 1
    this one works on my end too. thank you! – aronccs Mar 04 '22 at 14:40
  • This was a solution for me as well, but not alone. I also had to put this in web.config in : `` `` – jornhd Nov 15 '22 at 07:10
  • 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. – Bluebaron Dec 09 '22 at 03:44
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.

David Ouwinga
  • 213
  • 1
  • 8
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.

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.

Keymatic
  • 309
  • 2
  • 5
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.

Andrew
  • 11
  • 1
1

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

Adriaan
  • 17,741
  • 7
  • 42
  • 75
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.

CarComp
  • 1,929
  • 1
  • 21
  • 47
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!

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>

lukasor
  • 41
  • 3