You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET使用OpenIdConnect出现IDX10501签名验证失败问题求助

问题根因

你只在应用启动时一次性拉取了OpenID Connect身份服务商的签名密钥,没有设置自动刷新逻辑。当身份服务商定期(你遇到的周期是10-12小时)轮换签名密钥后,本地缓存的旧密钥无法匹配新签发Token的签名,就会抛出IDX10501错误。重新保存配置会触发应用重启,再次拉取最新密钥所以临时恢复,等下一次密钥轮换就会复现问题。

解决步骤

1. 替换静态密钥配置逻辑

删掉手动拉取JWKS密钥的代码,依赖ConfigurationManager自带的配置自动刷新能力,不要将密钥写死为启动时拉取的静态值。

2. 配置自动刷新和密钥解析规则

调整ConfigurationManager的刷新间隔适配服务商的密钥轮换周期,同时配置密钥解析委托,当签名匹配失败时自动拉取最新密钥。

3. 移除冗余同步调用

不要用.Result同步调用异步方法避免线程死锁,中间件会自动处理配置的异步拉取逻辑。

修改后的核心代码

Public Sub ConfigureAuth(ByVal app As IAppBuilder)
    Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
    ' 配置ConfigurationManager,设置自动刷新间隔
    Dim configurationManager = New ConfigurationManager(Of OpenIdConnectConfiguration)(
    $"{authority}/.well-known/openid-configuration",
    New OpenIdConnectConfigurationRetriever(), New HttpDocumentRetriever()) With {
        .AutomaticRefreshInterval = TimeSpan.FromHours(6), ' 每6小时主动刷新一次配置和密钥
        .RefreshInterval = TimeSpan.FromMinutes(1) ' 校验失败后最短1分钟可重试刷新
    }

    ' 删掉原来手动拉取discoveryDocument和signingKeys的两行代码,也可以删掉整个GetSecurityKeyAsync方法

    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配置,换成以下配置
            .ConfigurationManager = configurationManager,
            .IssuerSigningKeyResolver = Function(token, securityToken, kid, validationParameters)
                ' 密钥匹配失败时自动拉取最新配置获取对应kid的密钥
                Dim latestConfig = configurationManager.GetConfigurationAsync(CancellationToken.None).Result
                Return latestConfig.SigningKeys.Where(Function(k) k.KeyId = kid)
            End Function,
            .RequireSignedTokens = True,
            .RequireExpirationTime = True,
            .ValidateLifetime = True,
            .ValidateAudience = True,
            .ValidAudience = clientId,
            .ValidateIssuer = True,
            .ValidIssuer = authority,
            .SaveSigninToken = True
        },
        ' 其余Notifications配置保持不变
        .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

内容的提问来源于stack exchange,提问作者tushi0407

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 06:36:03