OWIN OpenID Connect中的SecurityTokenSignatureKeyNotFoundException连接到Google的中间件

时间:2017-01-20 21:42:38

标签: google-oauth owin identityserver3 openid-connect

我们使用通用OpenID Connect中间件将Google用作使用IdentityServer3的外部身份提供商。我们没有设置MetadataAddress或任何特殊的TokenValidationParameters(所以应该根据Authority获取元数据,然后根据它填写参数,这应该没问题)。我们间歇性地得到以下错误。我提出的其他问题有这个错误似乎涉及不正确的自定义验证,并且不是断断续续的。

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

kid引用的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); 目前是https://www.googleapis.com/oauth2/v3/certs的3个键中的第2个。

我们的选项如下:

player.seek()

这是配置问题还是某种需要处理的瞬态错误(如果是这样的话)?最终客户正在进行一次重试(虽然我不认为它在等待),但这似乎没什么帮助。

1 个答案:

答案 0 :(得分:0)

这里的问题似乎是由于默认ConfigurationManager缓存导致5天的结果,而Google更频繁地滚动密钥(更像是每天)。使用OWIN中间件的默认行为,第一个带有无法识别的密钥的请求将失败,然后在下一个请求时它将刷新密钥。

解决方案是使用更快的AutomaticRefreshInterval传入您自己的ConfigurationManager。以下大多数设置与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);
    }