asp.net-web-api - 如何在 webapi 中验证 azure 活动目录令牌
问题描述
我正在尝试验证 angularapp 中的天蓝色活动目录令牌
我在 web api 中使用了以下代码
[HttpGet]
[Route("Validate")]
public JwtSecurityToken Validate(string token)
{
string stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningTokens = config.SigningTokens,
ValidateLifetime = false
};
JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();
SecurityToken jwt;
var result = tokendHandler.ValidateToken(token, validationParameters, out jwt);
return jwt as JwtSecurityToken;
}
代码在 处显示错误IssuerSigningTokens = config.SigningTokens
,并显示消息
TokenValidationParameters 不包含 IssuerSigningTokens 的定义
任何人都可以为我提供解决方案吗?
我也想从 validate 方法返回我自己的令牌。
解决方案
今天,我们可以使用jwtSecurityTokenHandler
with System.IdentityModel.Tokens.Jwt
。
注意 System.IdentityModel.Tokens.Jwt 版本 5.xx 需要 .NET Framework 5.x。如果目标框架是 .NET Framework 4.5.x 或 4.6.x,则采用 System.IdentityModel.Tokens.Jwt 包的最新稳定 4.xx 版本。
验证智威汤逊
public override async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
...
// validate JWT
try
{
await JwtValidator.ValidateJwtToken(token, cancellationToken);
}
catch (SecurityTokenException e)
{
var validationSucceeded = false;
Contract.Assert(validationSucceeded, $"{ErrorCode.UNAUTHORIZED}JWT validation failed ({e.Message}).");
}
...
}
public class JwtValidator
{
private const string STS_DISCOVERY_ENDPOINT_SUFFIX = ".well-known/openid-configuration";
private const string URI_DELIMITER = "/";
public static async Task<SecurityToken> ValidateJwtToken(string token, CancellationToken cancellationToken)
{
var aadInstance = "https://login.microsoftonline.com/{0}";
var tenant = "example.com";
var audience = "853fb202-4201-4e20-97ae-4d5840d9490f";
var authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
// Fetch configuration
var stsDiscoveryEndpoint = string.Concat(authority, URI_DELIMITER, STS_DISCOVERY_ENDPOINT_SUFFIX);
ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint);
var config = await configManager.GetConfigurationAsync(cancellationToken);
// extract issuer and token for validation
var issuer = config.Issuer;
var signingTokens = config.SigningTokens.ToList();
// validate token
var validationParameters = CreateTokenValidationParameters(signingTokens, issuer, audience);
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
SecurityToken jwt;
jwtSecurityTokenHandler.ValidateToken(token, validationParameters, out jwt);
return jwt;
}
private static TokenValidationParameters CreateTokenValidationParameters(List<SecurityToken> signingTokens, string issuer, string audience)
{
Contract.Requires(null != signingTokens);
Contract.Requires(!string.IsNullOrWhiteSpace(issuer));
return new TokenValidationParameters()
{
ValidAudience = audience,
ValidIssuer = issuer,
IssuerSigningTokens = signingTokens,
CertificateValidator = X509CertificateValidator.None,
ValidateLifetime = true
};
}
}
我也想从 validate 方法返回我自己的令牌。
当OpenIdConnectConfiguration configManager.GetConfigurationAsync(cancellationToken);
必须在异步上下文中调用 using 时,使用 await(暗示周围的方法必须是异步的)。
否则,方法调用GetConfigurationAsync(cancellationToken)
永远不会返回。即使我尝试通过调用 .Result 或使用其他机制同步运行异步方法来同步运行异步方法,该方法也没有返回。
您可以在此博客中查看有关针对 Azure Active Directory 进行手动 JWT 验证的更多详细信息。
推荐阅读
- php - 将mysql代码转换成mysqli
- python - 在 Google Colab 笔记本中安装 tsne:错误:命令“x86_64-linux-gnu-gcc”失败,退出状态为 1
- c - 虽然循环不起作用?
- delphi - Delphi - TDBGrid 不会更新
- node.js - $facet 如何提高 $lookup 性能
- python-3.x - 自动将旧的字符串格式样式转换为 f 字符串
- vim - 如何在vim中设置设置多个颜色列/ cc(:set colorcolumn)?
- python - 使用select匹配一个类和一个元素beautifulSoup报错
- c++ - 错误:没有匹配的函数调用 std::thread
- c# - 如何在一组对象中查找特定值?