AzureAD / azure-activedirectory-identitymodel-extensions-for-dotnet

IdentityModel extensions for .Net
MIT License
1.05k stars 396 forks source link

IDX10500: Signature validation failed for some but not all servers. #551

Closed amayer171 closed 7 years ago

amayer171 commented 7 years ago

I'm having a similar issue to https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/545 where the kid seems to be an issue, but only for certain servers. We have other servers in the same network which are working with the same test case. Also by using a different tennant, the login works successfully. I currently able to reproduce locally in my test environment and when deployed to our development server.

Microsoft.Owin 3.0.1.0 System.Web.Mvc 5.2.3.0 System.IdentityModel.Tokens.Jwt 4.0.30826.1200 Microsoft.IdentityModel.Protocol.Extensions 1.0.3.42 Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.36371

One thing special about my case is the authentication type is "amr":["wia"]. We are using a corporate Azure AD instance. When a use my personal Azure AD tennant the issue does not occur and the amr is set to pwd.

I was able to recreate this using the sample application located at (i tried the existing code and updating to the latest nuget packages): https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect.

Error message:

System.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier ( IsReadOnly = False, Count = 2, Clause[0] = X509ThumbprintKeyIdentifierClause(Hash = 0x61B44041161C13F9A8B56549287AF02C16DDFFDB), Clause[1] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause ) ', token: '{"typ":"JWT","alg":"RS256","x5t":"YbRAQRYcE_motWVJKHrwLBbd_9s","kid":"YbRAQRYcE_motWVJKHrwLBbd_9s"}.{"aud":"9970bfed-1a0e-43fd-8926-6c0bf7e85d35","iss":"https://sts.windows.net/816af887-575b-4126-ae1e-f2faf045a465/","iat":1481743035,"nbf":1481743035,"exp":1481746935,"amr":["wia"],"c_hash":"HalFWJjR6mEx2fiT6X0VKg","family_name":"User","given_name":"Joe","ipaddr":"63.168.109.35","name":"User, Joe","nonce":"636173401346975465.MGJjNzBjMGMtZWUwNi00ZmIwLWFjYzktMTczODFmNTI3YWZlOWE5ZGNmZDYtYjk4OC00M2FlLWI5ZWYtZGEwNmE1OGZkMWVl","oid":"78cc6786-ebe9-4136-8874-61d944447b03","onprem_sid":"S-1-5-21-3564844935-3690257893-3571408573-5436","platf":"3","sub":"7FlNhtY0gilmgBjzlGPmPh23ANRJfuC8RCOUeISEMfU","tid":"816af887-575b-4126-ae1e-f2faf045a465","unique_name":"juser@*****.com","upn":"juser@*****.com","ver":"1.0"}'.

Setup code:

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

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,
                RedirectUri = postLogoutRedirectUri,
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = context => 
                    {
                        context.HandleResponse();
                        context.Response.Redirect("/Error?message=" + context.Exception.Message);
                       return Task.FromResult(0);
                    }
                }
            });
    }`

Stack Trace:

System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters) +1946 System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateToken(String securityToken, TokenValidationParameters validationParameters, SecurityToken& validatedToken) +158 Microsoft.IdentityModel.Extensions.SecurityTokenHandlerCollectionExtensions.ValidateToken(SecurityTokenHandlerCollection tokenHandlers, String securityToken, TokenValidationParameters validationParameters, SecurityToken& validatedToken) +194 Microsoft.Owin.Security.OpenIdConnect.<AuthenticateCoreAsync>d__1a.MoveNext() +4328 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32 Microsoft.Owin.Security.OpenIdConnect.<AuthenticateCoreAsync>d__1a.MoveNext() +7955 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +49 Microsoft.Owin.Security.Infrastructure.d0.MoveNext() +1008 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84 Microsoft.Owin.Security.Infrastructure.d0.MoveNext() +483 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d5.MoveNext() +291 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84 Microsoft.Owin.Security.Infrastructure.d0.MoveNext() +1107 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d5.MoveNext() +291 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d2.MoveNext() +293 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +32 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +208 System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +434 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.36371`

Theory:

I was thinking this may be an issue with discovery since the JWT kid (YbRAQRYcE_motWVJKHrwLBbd_9s) is not found in the discovery keys listed at https://login.microsoftonline.com/common/discovery/keys.

I'm also thinking this may be an issue with the step between login.microsoftonline and office365 which appears to be a saml workflow.

brentschmaltz commented 7 years ago

@amayer171 I don't believe 0x61B44041161C13F9A8B56549287AF02C16DDFFDB is a valid hash. Is cert from the AAD discovery endpoint? Did you IdentityModel OpenIdConnectConfigurationManager to retrieve the keys?

amayer171 commented 7 years ago

I'm not supplying a cert at all so it should be from AAD. Any advice on how to verify this?

I did not explicitly retrieve the keys. You can see the code sample i am using here: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect

Failure and Success JWT's are provided below. Interestingly the oid and aud are different.

The login flow is this:

  1. localhost (test app)
  2. login.microsoftonline.com
  3. office365 login prompt
  4. login.microsoftonline.com
  5. localhost (test app)

Fail Example

For a failed example i get the following JWT returned from login.microsoftonline.com: { typ: "JWT", alg: "RS256", x5t: "YbRAQRYcE_motWVJKHrwLBbd_9s", kid: "YbRAQRYcE_motWVJKHrwLBbd_9s" }. { aud: "9970bfed-1a0e-43fd-8926-6c0bf7e85d35", iss: "https://sts.windows.net/816af887-575b-4126-ae1e-f2faf045a465/", iat: 1481840142, nbf: 1481840142, exp: 1481844042, amr: [ "pwd" ], c_hash: "PFBr2GY7DmNcb4m-HmVO6Q", family_name: "User", given_name: "Joe", ipaddr: "72.215.186.200", name: "User, Joe", nonce: "636174371176006560.N2Y3MGQ0YzQtZDNmYy00NGMxLTk4MDItMWE1MmJiNzM0ODU0Yzk1YzgwMDEtZTdmMi00MDJiLTllZjAtNzMxOTFkYzdiZTQ5", oid: "78cc6786-ebe9-4136-8874-61d944447b03", onprem_sid: "S-1-5-21-3564844935-3690257893-3571408573-5436", platf: "3", sub: "7FlNhtY0gilmgBjzlGPmPh23ANRJfuC8RCOUeISEMfU", tid: "816af887-575b-4126-ae1e-f2faf045a465", unique_name: "juser@****.com", upn: "juser@****.com", ver: "1.0" }

Success Example

For a successful login i get the following. The difference in quotes is due to how this information was collected. { "typ":"JWT","alg":"RS256","x5t":"RrQqu9rydBVRWmcocuXUb20HGRM","kid":"RrQqu9rydBVRWmcocuXUb20HGRM" }.{ "aud":"afa4435a-86ea-4691-b350-97735bc3fc0d", "iss":"https://sts.windows.net/816af887-575b-4126-ae1e-f2faf045a465/", "iat":1481827780, "nbf":1481827780, "exp":1481831680, "amr":["wia"], "c_hash":"GmF2HbXTYMyWgZM3f2vKVQ" ,"family_name":"joe" ,"given_name":"user", "ipaddr":"63.168.109.35", "name":"user, joe","nonce":"636174248691399034.NDdhNzNjYjYtNDI5Zi00MDg5LWE0MjYtMjhlMjRmY2Q2Zjc1Yjk0MjcwYWUtODI5MC00NTg5LWEzZjUtYzFiZWI3YWMyNjll", "oid":"f622c7e4-b578-4618-8c45-52fa5fbfeff8", "onprem_sid":"S-1-5-21-3564844935-3690257893-3571408573-5852", "platf":"3", "sub":"wgX0PG-8C2-dbNPxXdr7_u0HnrxVTNBP_XsejXBP3I8", "tid":"816af887-575b-4126-ae1e-f2faf045a465", "unique_name":"juser@****.com", "upn":"juser@****.com", "ver":"1.0" }

amayer171 commented 7 years ago

This has been solved. It was a configuration issue that made it into the web.config file where the clientID and authority were wrong. The issue was fixed by using the latest values from azure active directory.