asp.net-mvc - 使用 JWK 在 C# 中验证 JWT token

标签 asp.net-mvc jwt asp.net-identity-3

我有 id_token 和 access_token 的 JsonWebKeys(JWK)。然后我从/token url 获取了我的 id_token。 如何在 C# 中使用 JWK 验证此 JWT id_token。

不用说,我已经尝试了几乎所有方法,但(IdenityModels.Jwt 等)但 JwtSecurityTokenHandler 不采用 JsonWebKey。 我使用 RS512 作为签名算法。

最佳答案

我刚刚自己实现了 Google IdToken 验证:

var parameters = new TokenValidationParameters
{
    ...
    IssuerSigningKeyResolver = await keyProvider.GetIssuerSigningKeyResolverAsync(cancellationToken),
};

SecurityToken token;
var handler = new JwtSecurityTokenHandler();
var principal = handler.ValidateToken(source, parameters, out token);

其中 keyProvider 是:

public class GoogleOAuth2KeyProvider
{
    private readonly IGoogleAuthConfiguration configuration;
    private Jwk lastCertResponse;
    private DateTimeOffset lastCertExpires;

    public GoogleOAuth2KeyProvider(IGoogleAuthConfiguration configuration)
    {
        this.configuration = configuration;
    }

    public async Task<IssuerSigningKeyResolver> GetIssuerSigningKeyResolverAsync(CancellationToken cancellationToken)
    {
        await UpdateCert(cancellationToken);

        var keys = lastCertResponse.Keys
            .Where(key => key.Kty == "RSA" && key.Use == "sig")
            .ToDictionary(key => key.Kid, StringComparer.InvariantCultureIgnoreCase);
        return new IssuerSigningKeyResolver((token, securityToken, keyIdentifier, tokenValidationParameters) =>
        {
            foreach (var keyIdentifierClause in keyIdentifier)
            {
                Jwk.KeysData key;
                if (!keys.TryGetValue(keyIdentifierClause.Id, out key))
                {
                    continue;
                }
                var rsa = RSA.Create();
                rsa.ImportParameters(new RSAParameters
                {
                    Exponent = Base64UrlEncoder.DecodeBytes(key.E),
                    Modulus = Base64UrlEncoder.DecodeBytes(key.N),
                });
                return new RsaSecurityKey(rsa);
            }
            return null;
        });
    }

    private async Task UpdateCert(CancellationToken cancellationToken)
    {
        if (lastCertResponse != null && DateTimeOffset.UtcNow < lastCertExpires)
        {
            return;
        }
        var initializer = new BaseClientService.Initializer
        {
            ApiKey = configuration.ServerApiKey,
        };
        using (var service = new Oauth2Service(initializer))
        {
            lastCertResponse = await service.GetCertForOpenIdConnect().ExecuteAsync(cancellationToken);
            lastCertExpires = DateTimeOffset.UtcNow.AddHours(12);
        }
    }
}

RSA 等只是 System.Security.Cryptography,而 Base64UrlEncoder 来自 System.IdentityModel (但很容易自己做)

不幸的是,它看起来不像 other kty / alg values很容易支持,例如没有 ECDsa.ImportParameters(),它需要来自 byte[] 的通用 CngKey,所以有人在做通用 .NET JWK 库时会有大概是打包 xy 参数本身。

关于asp.net-mvc - 使用 JWK 在 C# 中验证 JWT token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35648544/

相关文章:

html - 显示以逗号分隔且末尾没有逗号的值列表

c# - 过滤器可以从我的 BaseController 访问属性吗?

asp.net-mvc - 将url字符串作为参数传递给mvc Controller

c# - 将模型转换为 MVC 测试中的列表

android - 如何使用 JWT 将报价保存到 Google 电子钱包?

angular - 将授权 header 添加到 Springfox

token - JWT token 中 "kid"声明的含义是什么?

asp.net - AspNetCore 中间件 UserManager 依赖注入(inject)

c# - 在 ASP.NET Core Identity 中检查具有 Authorize 属性的多个策略之一