首页 > 解决方案 > 每日获取 :: SecurityTokenSignatureKeyNotFoundException: IDX10501: 签名验证失败。无法匹配键:

问题描述

我有 vb.net 应用程序,我正面临这个 IDX10501:签名验证失败。无法匹配键:问题。我的代码可以正常工作 10-12 小时,但之后我开始遇到这个问题。但是只要我重新保存配置而不更改任何内容,它就会开始工作。然后在 10-12 小时后我开始面临同样的问题。我想这与签名密钥有关。任何帮助,将不胜感激。我正在使用 OpenAthens.Owin.Security.OpenIdConnect 来实现 . 此外,即使我收到此错误,我也会正确获取 Kid 和 token 值。 启动.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)

标签: vb.netasp.net-identityowinopenid-connect

解决方案


在生产中,您需要解决几个不同的问题:

  1. IdentityServer令牌签名密钥必须配置并存储在您的服务之外,以便在重新部署期间保持相同。

  2. 需要配置每个 ASP.NET Core 服务中的数据保护 API ,以便保留加密密钥和密钥环。因此在重新部署期间也是如此。您需要这样做,以便在重新部署后接受所有已发布的 cookie。


推荐阅读