1

We want to switch our web apps to using Azure AD for authentication.

I'm using the example at: https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect

It wouldn't work initially but after some modifications I got authentication to work. But when it redirects back to my app I get this error: IDX10501: Signature validation failed. Unable to match key: kid

I'm using https://login.microsoftonline.com/{0}/v2.0 for the authority where {0} is my tenant id.

This is the authentication code

        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            // Custom middleware initialization. This is activated when the code obtained from a code_grant is present in the querystring (&code=<code>).
            app.UseOAuth2CodeRedeemer(
                new OAuth2CodeRedeemerOptions
                {
                    ClientId = AuthenticationConfig.ClientId,
                    ClientSecret = AuthenticationConfig.ClientSecret,
                    RedirectUri = AuthenticationConfig.RedirectUri
                });

            IdentityModelEventSource.ShowPII = true;
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    // This is needed for PKCE and resposne type must be set to 'code'
                    UsePkce = true,
                    ResponseType = OpenIdConnectResponseType.Code,

                    // The `Authority` represents the v2.0 endpoint - https://login.microsoftonline.com/{0}/v2.0
                    Authority = AuthenticationConfig.Authority,
                    ClientId = AuthenticationConfig.ClientId,
                    ClientSecret = AuthenticationConfig.ClientSecret,
                    RedirectUri = AuthenticationConfig.RedirectUri,
                    PostLogoutRedirectUri = AuthenticationConfig.RedirectUri,
                    Scope = AuthenticationConfig.BasicSignInScopes + " Mail.Read User.Read", // a basic set of permissions for user sign in & profile access "openid profile offline_access"
                    TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = false
                    },
                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthorizationCodeReceived = OnAuthorizationCodeReceived,
                        AuthenticationFailed = OnAuthenticationFailed,
                        RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                    },
                    // Handling SameSite cookie according to https://learn.microsoft.com/en-us/aspnet/samesite/owin-samesite
                    CookieManager = new SameSiteCookieManager(
                                     new SystemWebCookieManager())
                });
        }

        private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> arg)
        {
            arg.ProtocolMessage.SetParameter("myNewParameter", "its Value");
            return Task.CompletedTask;
        }

        private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
        {
            context.TokenEndpointRequest.Parameters.TryGetValue("code_verifier", out var codeVerifier);

            // Upon successful sign in, get the access token & cache it using MSAL
            IConfidentialClientApplication clientApp = MsalAppBuilder.BuildConfidentialClientApplication();
            AuthenticationResult result = await clientApp.AcquireTokenByAuthorizationCode(new[] { "Mail.Read User.Read" }, context.Code)
                .WithSpaAuthorizationCode() //Request an authcode for the front end
                .WithPkceCodeVerifier(codeVerifier) // Code verifier for PKCE
                .ExecuteAsync();

            HttpContext.Current.Session.Add("Spa_Auth_Code", result.SpaAuthCode);

            // This continues the authentication flow using the access token and id token retrieved by the clientApp object after
            // redeeming an access token using the access code.
            //
            // This is needed to ensure the middleware does not try and redeem the received access code a second time.
            context.HandleCodeRedemption(result.AccessToken, result.IdToken);
        }

        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            //notification.HandleResponse();
            //notification.Response.Redirect("/Error?message=" + notification.Exception.Message);
            return Task.FromResult(0);
        }

How do I get it to validate the signature?

Thanks, Skye

Skye MacMaster
  • 894
  • 1
  • 10
  • 19

1 Answers1

-1

Please check if below points help:

On successful authentication, Azure AD issues a signed JWT token (id token or access token). The resource application needs to know the public key of the certificate used sign the token in order to validate the token signature . An OWIN asp.net application can throw the following error IDX10501: Signature validation failed. Unable to match ‘kid’ or IDX10501: Signature validation failed. Unable to match key when it’s not able to find the kid to validate the token signature:

  • Please check and add valid audience and issuer. And check if the kid its validating is for symmetric key.
  • Check if you are passing the correct metadata endpoint.

ex: app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { // Sets the ClientId, authority, RedirectUri as obtained from web.config ClientId = clientId, Authority = authority, RedirectUri = redirectUri, MetadataAddress = "https://login.microsoftonline.com//.well-known/openid-configuration?appid=" PostLogoutRedirectUri = redirectUri,

var configManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{validissuers.Last()}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());

var openidconfig = configManager.GetConfigurationAsync().Result;

TokenValidationParameters = new TokenValidationParameters()
                    {

            ValidateAudience = true,
            ValidAudience = config.Resource,

            ValidateIssuer = true,
            ValidIssuers = new[] { config.GetAuthority() },

            ValidateIssuerSigningKey = true,
            IssuerSigningKeys = openidconfig.SigningKeys,

            //or       IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SuperSecretPassword2"))
                    
}

    }

Azure AD by default uses a certificate to sign an OAuth2 JWT token using an asymmetric algorithm (RS256). Alternatively a JWT token can be signed with a “shared” secret using a symmetric algorithm (HS256).

References:

  1. get a symmetric key signing token (aaddevsup.xyz)
  2. c# - IDX10501- Stack Overflow
kavyaS
  • 8,026
  • 1
  • 7
  • 19