如何在webapi

时间:2018-05-15 11:17:07

标签: asp.net-web-api azure-active-directory

我正在尝试验证在angularapp中获得的azure活动目录令牌

我在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

任何人都能为我提供解决方案吗?

此外,我想从验证方法返回我自己的令牌。

1 个答案:

答案 0 :(得分:1)

今天,我们可以将jwtSecurityTokenHandlerSystem.IdentityModel.Tokens.Jwt一起使用。

<强>注意 System.IdentityModel.Tokens.Jwt版本5.x.x需要.NET Framework 5.x. 如果目标框架是.NET Framework 4.5.x或4.6.x,请使用最新的4.x.x版本的System.IdentityModel.Tokens.Jwt软件包。

验证JWT

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
        };
    }
}
  

此外,我想从验证方法返回我自己的令牌。

使用await时必须在异步上下文中调用OpenIdConnectConfiguration configManager.GetConfigurationAsync(cancellationToken);(意味着周围的方法必须是异步的)。

否则方法调用GetConfigurationAsync(cancellationToken)永远不会返回。即使我试图通过调用.Result或使用其他机制同步运行异步方法同步运行异步方法,同步方法也没有返回。

您可以在this blog中查看有关针对Azure Active Directory的手动JWT验证的更多详细信息。