每日获取 :: 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: 签名验证失败。无法匹配键:的主要内容,如果未能解决你的问题,请参考以下文章

获取Bing每日图片API接口

如何从 HealthKit 中获取每日平均步数

如何使用 google adwords api 获取每日报告?

SQL获取每日注册用户总数

python+tushare获取股票每日停复牌信息

如何获取 Youtube API 配额的每日使用量?