如何在WebAPI中验证Azure AD令牌并解决代码错误、返回自定义令牌
解决方案:修复令牌验证错误并返回自定义令牌
一、修复IssuerSigningTokens的错误问题
你遇到的编译错误是因为**TokenValidationParameters类已经不再包含IssuerSigningTokens属性**——这个属性在较新的Microsoft.IdentityModel.Tokens版本中被移除了,取而代之的是IssuerSigningKeys,用来接收签名密钥集合。
你需要把代码里的IssuerSigningTokens = config.SigningTokens替换为IssuerSigningKeys = config.SigningKeys,同时建议把同步的.Result改成异步await(避免潜在的死锁问题)。
二、返回自定义令牌的实现
要返回自定义令牌,你可以先定义一个符合需求的DTO(数据传输对象),然后将验证后的JWT令牌信息映射到这个DTO中返回。
完整修改后的代码示例
首先定义自定义令牌模型:
// 自定义令牌响应模型,根据你的需求添加/调整字段 public class CustomTokenResponse { public string TokenId { get; set; } public string Subject { get; set; } public DateTime? ExpirationTime { get; set; } public DateTime? IssuedTime { get; set; } public Dictionary<string, string> KeyClaims { get; set; } }
然后修改你的Validate方法:
[HttpGet] [Route("Validate")] public async Task<IActionResult> Validate(string token) { string stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"; // 使用异步方式获取配置,避免.Result导致的线程死锁 ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>( stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever()); OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync(); TokenValidationParameters validationParameters = new TokenValidationParameters { ValidateAudience = false, ValidateIssuer = false, // 替换为当前版本库支持的IssuerSigningKeys属性 IssuerSigningKeys = config.SigningKeys, ValidateLifetime = false }; JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); SecurityToken validatedToken; try { // 执行令牌验证 ClaimsPrincipal validationResult = tokenHandler.ValidateToken(token, validationParameters, out validatedToken); // 将验证后的JWT转换为自定义响应模型 var jwtToken = validatedToken as JwtSecurityToken; var customToken = new CustomTokenResponse { TokenId = jwtToken.Id, Subject = jwtToken.Subject, ExpirationTime = jwtToken.ValidTo, IssuedTime = jwtToken.ValidFrom, KeyClaims = jwtToken.Claims.ToDictionary(c => c.Type, c => c.Value) }; return Ok(customToken); } catch (SecurityTokenException ex) { // 捕获并返回令牌验证失败的具体原因 return BadRequest($"令牌验证失败: {ex.Message}"); } }
关键说明
- 属性替换:
IssuerSigningKeys是当前版本Microsoft.IdentityModel.Tokens库中用来指定签名密钥的正确属性,它接收IEnumerable<SecurityKey>类型,而config.SigningKeys正好匹配这个类型要求。 - 异步优化:把
.Result改成await是ASP.NET Core环境下的最佳实践,能避免同步阻塞引发的线程死锁问题。 - 自定义模型:通过
CustomTokenResponse你可以灵活控制返回给前端的字段,比如只保留业务需要的声明、时间信息,而不是返回整个JwtSecurityToken对象。 - 异常处理:添加
try-catch块捕获令牌验证失败的异常,返回更友好的错误提示,方便前端排查问题。
内容的提问来源于stack exchange,提问作者rakshith
相关产品推荐
相关产品推荐

