我们使用通用的OpenID Connect中间件,使用Google作为使用IdentityServer3的外部身份提供者。我们没有设置元数据地址或任何特殊的令牌验证参数(所以它应该基于权威获取元数据,然后基于它填写参数,这应该没问题)。我们间歇性地收到以下错误。我提出的其他有此错误的问题似乎涉及不正确的自定义验证,并且不是间歇性的。
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
目前是 3 个键中的第 2 个 https://www.googleapis.com/oauth2/v3/certs。
我们的选项如下所示:
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);
这是需要处理的配置问题还是某种暂时性错误(如果是,如何处理)?最终客户端正在重试一次(尽管我认为它根本没有等待),但这似乎没有帮助。
这里的问题似乎是由于默认的 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);
}