skip to Main Content

I have some weird error when trying to set up AD authentication in an old legacy WebForms app. I have upgraded the solution to use .NET Framework 4.8 and installed the nuget packages.

As a last resort I tried creating a new .NET Framework 4.8 WebForms app in VS 2022 and set it up to use AAD authentication. Now this works flawlessly on my local dev machine (I pointed the response URL to be https://localhost:7308 the port assigned).

However if I put the site up on my live server (Windows Server 2019 running IIS) and repoint the response URL for the AAD to point to that one all I get is this error:

Exception type: OpenIdConnectProtocolInvalidNonceException
Exception message: IDX21323: RequireNonce is ‘[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]’.
OpenIdConnectProtocolValidationContext.Nonce was null,

This is the code I have right now (I’ve tried changing the cookie settings)

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            CookieManager = new SystemWebCookieManager(),
            CookieSameSite = Microsoft.Owin.SameSiteMode.Lax,
            CookieHttpOnly = true,
            CookieSecure = CookieSecureOption.Never
        });

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,
                RequireHttpsMetadata = false,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthenticationFailed = (context) =>
                    {
                        return System.Threading.Tasks.Task.FromResult(0);
                    },

                    SecurityTokenValidated = (context) =>
                    {
                        string name = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
                        context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
                        return System.Threading.Tasks.Task.FromResult(0);
                    }
                }
            });

I have also tried setting the AuthenticationFailed to

                    AuthenticationFailed = (context) =>
                    {
                        if (context.Exception.Message.Contains("IDX21323"))
                        {
                            context.HandleResponse();
                            context.OwinContext.Authentication.Challenge();
                        }

                        return Task.FromResult(true);
                    },

But that only sends me into a loop where I get the AAD login screen over and over again.

I have one suspicion. The set up we have in our live environment is a HAPRoxy that takes care of routing traffic to the various web servers we have. That one also handles SSL, so all traffic that hit my actual IIS server comes in as plain HTTP traffic. But I have no idea if

  1. AAD Authentication can work in a setup like that or
  2. I need to have an actual SSL cert set up on the IIS machine in order to handle this

I’ve tried googling my eyes out for this but so far it’s been to no avail, so then I leave it in the warm hands of the SO community.

Anyone have any ideas regarding this?

2

Answers


  1. Chosen as BEST ANSWER

    The final solution for anyone else stumbling upon this issue was this one: https://learn.microsoft.com/en-us/aspnet/samesite/owin-samesite

    Harshitas response is also relevant but might not solve the issue completely.


  2. Iam able to authenticate the Web Forms .NET 4.8 and able to login without any issues.

    Make sure you have added the Redirect URI for the deployed App.

    enter image description here

    My StartupAuth.cs:

    The difference I found in my code is CookieAuthenticationOptions (CookieManager, CookieSameSite, CookieHttpOnly, CookieSecure)
    are not set.

    using System;
    using System.Configuration;
    using System.Security.Claims;
    using Microsoft.Owin.Extensions;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.OpenIdConnect;
    using Owin;
    
    namespace WebApplication1
    {
        public partial class Startup
        {
            private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
            private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]);
            private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
            private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
    
            string authority = aadInstance + tenantId + "/v2.0";
    
            public void ConfigureAuth(IAppBuilder app)
            {
                app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
                app.UseCookieAuthentication(new CookieAuthenticationOptions());
    
                app.UseOpenIdConnectAuthentication(
                    new OpenIdConnectAuthenticationOptions
                    {
                        ClientId = clientId,
                        Authority = authority,
                        PostLogoutRedirectUri = postLogoutRedirectUri,
    
                        Notifications = new OpenIdConnectAuthenticationNotifications()
                        {
                            AuthenticationFailed = (context) =>
                            {
                                return System.Threading.Tasks.Task.FromResult(0);
                            },
    
                            SecurityTokenValidated = (context) =>
                            {
                                string name = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
                                context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
                                return System.Threading.Tasks.Task.FromResult(0);
                            }
                        }
                    });
    
                // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
                app.UseStageMarker(PipelineStage.Authenticate);
            }
    
            private static string EnsureTrailingSlash(string value)
            {
                if (value == null)
                {
                    value = string.Empty;
                }
    
                if (!value.EndsWith("/", StringComparison.Ordinal))
                {
                    return value + "/";
                }
    
                return value;
            }
        }
    }
    

    AppSettings in web.config:

     <appSettings>
        <add key="ida:ClientId" value="********" />
        <add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
        <add key="ida:Domain" value="****.onmicrosoft.com" />
        <add key="ida:TenantId" value="********" />
        <add key="ida:PostLogoutRedirectUri" value="https://localhost:44305/signin-oidc" />
      </appSettings>
    

    Local Output:

    enter image description here

    Deployed Azure App Service Output:

    enter image description here

    I need to have an actual SSL cert set up on the IIS machine in order to handle this

    Refer this document by globalsign to install SSL Certificate on IIS.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search