【问题标题】:IDX11008: This method is not supported to validate a 'jwt' use the method: ValidateToken(String, TokenValidationParameters, out SecurityToken)IDX11008:此方法不支持验证 'jwt' 使用方法:ValidateToken(String, TokenValidationParameters, out SecurityToken)
【发布时间】:2023-03-27 19:49:01
【问题描述】:

这曾经有效...

回到...我有一个自定义的securityTokenHandler。我更新到 3.02 版本,我能够删除自定义处理程序并直接引用 JwtSecurityTokenHandler

<securityTokenHandlers>
  <add type="System.IdentityModel.Tokens.JwtSecurityTokenHandler,
             System.IdentityModel.Tokens.Jwt" />
  <securityTokenHandlerConfiguration>
    <certificateValidation certificateValidationMode="PeerTrust" />
  </securityTokenHandlerConfiguration>
</securityTokenHandlers>

这似乎是一种改进。所以从那以后我一直在使用它。

现在我更新到 4.0.0 并收到此错误...

[NotSupportedException: IDX11008: This method is not supported to validate a 'jwt' use the method: ValidateToken(String, TokenValidationParameters, out SecurityToken).]
   System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateToken(SecurityToken token) +46
   System.IdentityModel.Tokens.SecurityTokenHandlerCollection.ValidateToken(SecurityToken token) +73
   System.IdentityModel.Services.TokenReceiver.AuthenticateToken(SecurityToken token, Boolean ensureBearerToken, String endpointUri) +120
   System.IdentityModel.Services.WSFederationAuthenticationModule.SignInWithResponseMessage(HttpRequestBase request) +493
   System.IdentityModel.Services.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +364
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

看东西,ValidateToken() 方法已完全弃用。所以...我想知道如何通过来自 web.config 的被动重定向调用ValidateToken(String, TokenValidationParameters, out SecurityToken)?我是否必须再次将其包装在自定义处理程序中,还是需要做一些不同的事情?

谢谢

【问题讨论】:

    标签: c# wif jwt


    【解决方案1】:

    是的,有重大变化。万一其他人遇到这种情况,从 Nuget 的 4.0.2.202250711 版本开始,您需要执行类似以下操作:

    public class CustomTokenSecurityHandler : System.IdentityModel.Tokens.JwtSecurityTokenHandler
    {
        private const string KeyName = "http://somesite.com/url";
        private const string ValidIssuerString = "http://somesite.com/url";
    
        public override System.Collections.ObjectModel.ReadOnlyCollection<System.Security.Claims.ClaimsIdentity> ValidateToken(SecurityToken token)
        {
            var idConfig = System.IdentityModel.Configuration.SystemIdentityModelSection.Current.IdentityConfigurationElements.GetElement("");
    
             var validationParameters = new TokenValidationParameters()
            {
                ValidAudience = (idConfig.AudienceUris.Cast<AudienceUriElement>().First()).Value
            };
    
             // set up valid issuers
             if ((validationParameters.ValidIssuer == null) &&
                 (validationParameters.ValidIssuers == null || !validationParameters.ValidIssuers.Any()))
             {
                 validationParameters.ValidIssuers = new List<string> { ValidIssuerString };
             }
             // and signing token.
             if (validationParameters.IssuerSigningToken == null)
             {
                 var resolver = (NamedKeyIssuerTokenResolver)this.Configuration.IssuerTokenResolver;
                 if (resolver.SecurityKeys != null)
                 {
                     IList<SecurityKey> skeys;
                     if (resolver.SecurityKeys.TryGetValue(KeyName, out skeys))
                     {
                         var tok = new NamedKeySecurityToken(KeyName, "id", skeys);
                         validationParameters.IssuerSigningToken = tok;
                     }
                 }
             }
    
            var tokenString = (token as JwtSecurityToken);
             ClaimsPrincipal validated = base.ValidateToken(tokenString.RawData, validationParameters, out token);
             var result = new ReadOnlyCollection<ClaimsIdentity>(validated.Identities.ToList());
             return result;
        }
    
    
    }
    

    与其他提供的答案的主要区别在于

    var tokenString = (token as JwtSecurityToken);
    ClaimsPrincipal validated = base.ValidateToken(tokenString.RawData, validationParameters, out token);
    var result = new ReadOnlyCollection<ClaimsIdentity>(validated.Identities.ToList());
    

    ValidateToken 方法现在只接受 3 个参数,而不是 2 个。您必须提供实际的令牌字符串、验证参数和 SecurityToken 对象作为参考。

    您还可以通过直接从 web.config 中的 System.Identity 配置部分读取来填充验证参数(参见上面的代码)。

    【讨论】:

      【解决方案2】:

      我们遇到了同样的问题。我们包装了标准处理程序以支持该方法:

      public override ReadOnlyCollection<ClaimsIdentity> ValidateToken( 
                                                            SecurityToken token)
      {
         ClaimsPrincipal validated = ValidateToken(token as JwtSecurityToken, 
                                                   validationParameters);
         var result = new ReadOnlyCollection<ClaimsIdentity>(
                             validated.Identities.ToList());
         return result;
      }
      

      在我们的例子中,我们从配置文件中读取验证参数。 (我们通过覆盖 public override void LoadCustomConfiguration(XmlNodeList nodeList) 来做到这一点,我们在其中定义了我们自己的验证参数格式。这允许我们将它们放入标准的 System.IdentityModel 配置中......

      【讨论】:

      • 谢谢威利。这几乎正​​是我不想听到的。这似乎是一种倒退而不是改进。也许外面有人对为什么现在这样。我原以为通过浏览器的被动身份验证是您想要支持的。
      【解决方案3】:

      我有同样的问题。我没有创建自定义处理程序,而是恢复到 System.IdentityModel.Tokens.Jwt 的 3.0.0.0 版本,一切都开始工作了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-11
        • 2019-12-24
        • 2014-11-07
        • 2020-04-23
        • 2020-04-13
        • 2020-12-06
        相关资源
        最近更新 更多