.NET 8中自定义Token验证器失效问题求助
问题分析与解决方案
错误根源
.NET 8 中,Microsoft Identity 组件默认使用 JsonWebTokenHandler 处理JWT令牌,而你的自定义验证器中仍在使用旧的 JwtSecurityTokenHandler。两者返回的令牌类型不匹配:JwtSecurityTokenHandler 返回 System.IdentityModel.Tokens.Jwt.JwtSecurityToken,但框架期望的是 Microsoft.IdentityModel.JsonWebTokens.JsonWebToken,因此触发了IDX10506签名验证错误。
修复步骤
1. 替换令牌处理程序类型
将自定义验证器中的 JwtSecurityTokenHandler 替换为 JsonWebTokenHandler,并确保引用正确的命名空间 Microsoft.IdentityModel.JsonWebTokens。
2. 补全未初始化属性
原代码中 CanValidateToken 属性未赋值,需设置为 true 才能让框架识别该验证器可执行验证逻辑。
修改后的代码示例
using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Tokens; using Serilog; using RestSharp; using System.Text.Json; public class PingTokenValidator : ISecurityTokenValidator { private readonly IConfiguration configuration; private readonly ILogger log; private readonly OpenIdConnectConfiguration openIdConnectConfiguration; private readonly JsonWebTokenHandler tokenHandler; // 替换为JsonWebTokenHandler public PingTokenValidator(OpenIdConnectConfiguration openIdConnectConfiguration, IConfiguration configuration) { this.tokenHandler = new(); this.openIdConnectConfiguration = openIdConnectConfiguration; this.configuration = configuration; this.log = Log.ForContext<PingTokenValidator>(); } public bool CanReadToken(string securityToken) { return true; } public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) { try { var principal = this.tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken); // 保留你的缓存逻辑(需补充tokenExistInCache和cachedToken的定义) if (tokenExistInCache && cachedToken == securityToken) { return principal; } if (!this.IsValid(securityToken)) { throw new SecurityTokenValidationException("Token not authorised by PingID."); } return principal; } catch (Exception e) { this.log.Error(e, "Error validating JWT token"); throw; } } public bool CanValidateToken { get; } = true; // 补全属性赋值 public int MaximumTokenSizeInBytes { get; set; } = TokenValidationParameters.DefaultMaximumTokenSizeInBytes; private bool IsValid(string securityToken) { var options = new RestClientOptions { Authenticator = new HttpBasicAuthenticator(this.configuration["FDID:UserId"]!, this.configuration["FDID:Secret"]!) }; var client = new RestClient(options); var request = new RestRequest(this.openIdConnectConfiguration.IntrospectionEndpoint, Method.Post); request.AddHeader("Content-Type", "application/x-www-form-urlencoded"); request.AddParameter("grant_type", "urn:pingidentity.com:oauth2:grant_type:validate_bearer"); request.AddParameter("token", securityToken); var response = client.Execute(request); if (!response.IsSuccessful) { this.log.Error(response.ErrorException, "Error validating JWT token. Response message: {@TokenIntrospectionMessage}", response.Content); return false; } if (string.IsNullOrWhiteSpace(response.Content)) { this.log.Error("Ping returned empty response: {@IntrospectionResponse}", response); return false; } var tokenSummary = JsonSerializer.Deserialize<PingTokenSummary>(response.Content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return tokenSummary is { Active: true }; } }
额外注意点
- 确保项目引用了
Microsoft.IdentityModel.JsonWebTokensNuGet包(.NET 8中通常已默认包含,缺失时需手动安装)。
内容的提问来源于stack exchange,提问作者Artur Michajluk
相关产品推荐
相关产品推荐

