每日获取 :: SecurityTokenSignatureKeyNotFoundException: IDX10501: 签名验证失败。无法匹配键:
Posted
技术标签:
【中文标题】每日获取 :: SecurityTokenSignatureKeyNotFoundException: IDX10501: 签名验证失败。无法匹配键:【英文标题】:Daily getting :: SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys: 【发布时间】:2021-09-09 02:37:25 【问题描述】:我有 vb.net 应用程序,我正面临这个 IDX10501:签名验证失败。无法匹配键:问题。我的代码可以正常工作 10-12 小时,但在那之后我开始遇到这个问题。但是只要我重新保存配置而不更改任何内容,它就会开始工作。然后在 10-12 小时后我开始面临同样的问题。我想这与签名密钥有关。任何帮助,将不胜感激。我正在使用 OpenAthens.Owin.Security.OpenIdConnect 来实现 .此外,即使我收到此错误,我也会正确获取 Kid 和 token 值。 Startup.vb 文件
Imports System.IdentityModel.Tokens.Jwt
Imports System.Net
Imports System.Net.Http
Imports System.Security.Claims
Imports System.Threading.Tasks
Imports Microsoft.IdentityModel.Protocols
Imports Microsoft.IdentityModel.Protocols.OpenIdConnect
Imports Microsoft.IdentityModel.Logging
Imports Microsoft.IdentityModel.Tokens
Imports Microsoft.Owin.Security
Imports Microsoft.Owin.Security.Cookies
Imports Newtonsoft.Json
Imports OpenAthens.Owin.Security.OpenIdConnect
Imports Owin
Public Class ExpectedJwksResponse
<JsonProperty(PropertyName:="keys")>
Public Property Keys As List(Of JsonWebKey)
End Class
Public Class Startup
Private ReadOnly clientId As String = ConfigurationManager.AppSettings("ClientId")
Private ReadOnly authority As String = ConfigurationManager.AppSettings("OrgUri")
Private ReadOnly clientSecret As String = ConfigurationManager.AppSettings("ClientSecret")
Private ReadOnly redirectUri As String = ConfigurationManager.AppSettings("RedirectUri")
Private ReadOnly callBackPath As String = ConfigurationManager.AppSettings("CallBackPath")
Private ReadOnly acr As String = ConfigurationManager.AppSettings("Acr")
Private ReadOnly acrValues As String = ConfigurationManager.AppSettings("AcrValues")
Public Sub Configuration(ByVal app As IAppBuilder)
ConfigureAuth(app)
End Sub
Public Sub ConfigureAuth(ByVal app As IAppBuilder)
Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim configurationManager = New ConfigurationManager(Of OpenIdConnectConfiguration)(
$"authority/.well-known/openid-configuration",
New OpenIdConnectConfigurationRetriever(), New HttpDocumentRetriever())
Dim discoveryDocument = configurationManager.GetConfigurationAsync().Result
Dim signingKeys = GetSecurityKeyAsync(discoveryDocument.JwksUri).Result
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)
IdentityModelEventSource.ShowPII = True
app.UseCookieAuthentication(New CookieAuthenticationOptions())
app.UseOpenIdConnectAuthentication(New OpenIdConnectAuthenticationOptions With
.GetClaimsFromUserInfoEndpoint = True,
.ClientId = clientId,
.ClientSecret = clientSecret,
.Authority = authority,
.ResponseType = OpenIdConnectResponseType.Code,
.RedirectUri = redirectUri,
.CallbackPath = Microsoft.Owin.PathString.FromUriComponent(New Uri(callBackPath)),
.TokenValidationParameters = New TokenValidationParameters() With
.IssuerSigningKeys = signingKeys,
.RequireSignedTokens = True,
.RequireExpirationTime = True,
.ValidateLifetime = True,
.ValidateAudience = True,
.ValidAudience = clientId,
.ValidateIssuer = True,
.ValidIssuer = authority,
.SaveSigninToken = True
,
.Notifications = New OpenIdConnectAuthenticationNotifications With
.RedirectToIdentityProvider = Function(n)
n.ProtocolMessage.SetParameter(acr, acrValues)
n.Response.Redirect(callBackPath)
n.ProtocolMessage.RedirectUri = callBackPath
Return Task.FromResult(0)
End Function,
.SecurityTokenValidated = Function(context)
Dim anc = Convert.ToString(context.ProtocolMessage.AccessToken)
Dim rawAccessToken As String = context.ProtocolMessage.AccessToken
Dim rawIdToken As String = context.ProtocolMessage.IdToken
Dim handler = New JwtSecurityTokenHandler()
Dim accessToken = handler.ReadJwtToken(rawAccessToken)
Dim idToken = handler.ReadJwtToken(rawIdToken)
context.Response.Redirect(callBackPath)
If (TypeOf context.AuthenticationTicket.Identity Is ClaimsIdentity) Then
Dim identity As ClaimsIdentity = New ClaimsIdentity
Dim claimsIdentity As ClaimsIdentity = CType(context.AuthenticationTicket.Identity, ClaimsIdentity)
Dim userId As String = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier).Value
identity.AddClaim(New Claim(ClaimTypes.GivenName, userId))
End If
Return Task.CompletedTask
End Function
)
End Sub
Private Async Function GetSecurityKeyAsync(ByVal jwksUri As String) As Task(Of List(Of SecurityKey))
Using client = New HttpClient()
Dim response = Await client.GetAsync(New Uri(jwksUri))
If response.IsSuccessStatusCode Then
Dim result = Await response.Content.ReadAsAsync(Of ExpectedJwksResponse)()
Dim keys = New List(Of SecurityKey)()
Dim i = 0
For Each key In result.Keys
keys.Add(key)
i = i + 1
Next
Return keys
End If
End Using
Return Nothing
End Function
End Class
挑战:
HttpContext.Current.GetOwinContext().Authentication.Challenge(New AuthenticationProperties With
.RedirectUri = ConfigurationManager.AppSettings("RedirectUri"), OpenIdConnectAuthenticationDefaults.AuthenticationType)
【问题讨论】:
您使用的是什么授权服务器?您是在生产过程中还是在本地开发过程中看到这一点? 这永远不会出现在本地环境中,而是出现在 dev 、 stage 和 prod 中。认证服务器是我们公司内部的认证服务器。 【参考方案1】:在生产中,您需要解决几个不同的问题:
IdentityServer token signing key 必须配置并存储在您的服务之外,以便在重新部署期间保持相同。
需要配置每个 ASP.NET Core 服务中的 Data Protection API,以便保留加密密钥和密钥环。因此在重新部署期间也是如此。您需要这样做,以便在重新部署后接受所有发出的 cookie。
【讨论】:
听不懂?我的应用程序不需要重新部署。即使我重新启动应用程序,它也开始工作。 一件事是在这里监控密钥,它们是一直相同还是在 10-12 小时后改变? youridentityserver/.well-known/openid-configuration/jwks 如何在生产中部署? 它正在从身份验证服务器更改,但我每次都无法获得最新的密钥。每当应用程序第一次在服务器上启动时,它都会获取密钥。我找不到方法,如何从服务器获取新密钥。作为这种挑战方法,不调用获取签名密钥的那一步。 如果您在生产环境中的启动类中有此语句 "AddDeveloperSigningCredential()" ,那么您需要做一些工作。以上是关于每日获取 :: SecurityTokenSignatureKeyNotFoundException: IDX10501: 签名验证失败。无法匹配键:的主要内容,如果未能解决你的问题,请参考以下文章