Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
301 views
in Technique[技术] by (71.8m points)

SecurityTokenSignatureKeyNotFoundException in OWIN OpenID Connect middleware connecting to Google

We are using the generic OpenID Connect middleware to use Google as an external identity provider using IdentityServer3. We don't have MetadataAddress or any special TokenValidationParameters set up (so it should be getting the metadata based on Authority, and then filling in parameters based on that, which should be fine). We are getting the following error highly intermittently. Other questions I've come up with that have this error seem to involve incorrect custom validation and are not intermittent.

Authentication Failed : Microsoft.IdentityModel.Protocols.OpenIdConnectMessage : System.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException : IDX10500 : Signature validation failed.Unable to resolve SecurityKeyIdentifier : 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
)
',
token : '{"alg":"RS256","kid":"74e0db263dbc69ac75d8bf0853a15d05e04be1a2"}.{"iss":"https://accounts.google.com","iat":1484922455,"exp":1484926055, <snip more claims>}'.
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)in c :   workspace  WilsonForDotNet45Release  src  System.IdentityModel.Tokens.Jwt  JwtSecurityTokenHandler.cs : line 943
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateToken(String securityToken, TokenValidationParameters validationParameters, SecurityToken & validatedToken)in c :   workspace  WilsonForDotNet45Release  src  System.IdentityModel.Tokens.Jwt  JwtSecurityTokenHandler.cs : line 671
at Microsoft.IdentityModel.Extensions.SecurityTokenHandlerCollectionExtensions.ValidateToken(SecurityTokenHandlerCollection tokenHandlers, String securityToken, TokenValidationParameters validationParameters, SecurityToken & validatedToken)in c :   workspace  WilsonForDotNet45Release  src  Microsoft.IdentityModel.Protocol.Extensions  SecurityTokenHandlerCollectionExtensions.cs : line 71
at Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler. < AuthenticateCoreAsync > d__1a.MoveNext()

The kid referred to is presently the 2nd of 3 keys at https://www.googleapis.com/oauth2/v3/certs.

Our Options look like this:

var options = new OpenIdConnectAuthenticationOptions
                {
                    AuthenticationType = "Google",
                    Caption = "Sign in with Google",
                    Scope = "openid email profile",
                    ClientId = clientId,
                    Authority = "https://accounts.google.com/",
                    AuthenticationMode = AuthenticationMode.Passive,
                    RedirectUri = new Uri(baseUri, "identity/signin-google").ToString(),
                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthenticationFailed = context => HandleException(context),
                        RedirectToIdentityProvider = context => AddLoginHint(context),
                    },
                    SignInAsAuthenticationType = signInAsType
                };

                app.UseOpenIdConnectAuthentication(options);

Is this a configuration issue or some sort of transient error that needs to be dealt with (and if so how)? The end client is doing one retry (though I don't think it's waiting at all) but that doesn't seem to help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem here seems to have been caused by the fact that the default ConfigurationManager caches results for 5 days, while Google rolls over their keys much more frequently (more like daily). With the default behavior of the OWIN middleware, the first request with an unrecognized key will fail, and then on the next request it will refresh the keys.

The solution is to pass in your own ConfigurationManager with a faster AutomaticRefreshInterval. Most of the settings below are as in OpenIdConnectAuthenticationMiddleware

private static void ConfigureIdentityProviders(IAppBuilder app, string signInAsType)
    {
        var baseUri = new Uri("https://localhost:44333");
        var googleAuthority = "https://accounts.google.com/";
        var metadataAddress = googleAuthority + ".well-known/openid-configuration";
        var httpClient = new HttpClient(new WebRequestHandler());
        httpClient.Timeout = TimeSpan.FromMinutes(1);
        httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
        var configMgr = new ConfigurationManager<OpenIdConnectConfiguration>(metadataAddress, httpClient)
                            {
                                // Default is 5 days, while Google is updating keys daily
                                AutomaticRefreshInterval
                                    =
                                    TimeSpan
                                    .FromHours(12)
                            };

        var options = new OpenIdConnectAuthenticationOptions
                          {
                              AuthenticationType = "Google",
                              Caption = "Google",
                              Scope = "openid email profile",
                              ClientId = GoogleClientId,
                              Authority = googleAuthority,
                              ConfigurationManager = configMgr,
                              AuthenticationMode = AuthenticationMode.Passive,
                              RedirectUri =
                                  new Uri(baseUri, "identity/signin-google").ToString(),
                              SignInAsAuthenticationType = signInAsType
                          };

        app.UseOpenIdConnectAuthentication(options);
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...