【问题标题】:Validate JWT token in C# using JWK使用 JWK 在 C# 中验证 JWT 令牌
【发布时间】:2016-02-26 09:57:57
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

    我刚刚为 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 参数,大概。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 2020-03-31
      • 2021-05-09
      • 2018-07-27
      • 2021-10-23
      • 2019-06-23
      • 2019-03-28
      相关资源
      最近更新 更多