3
我有id_token和JsonWebKeys的access_token(JWK)。然後我從/ token url獲得我的id_token。 如何在C#中使用JWK驗證此JWT id_token。驗證令牌JWT在C#中使用JWK
不用說,我已經試過幾乎所有的東西,但(IdenityModels.Jwt等),但JwtSecurityTokenHandler不採取JsonWebKey。 我使用RS512作爲簽名算法。
我有id_token和JsonWebKeys的access_token(JWK)。然後我從/ token url獲得我的id_token。 如何在C#中使用JWK驗證此JWT id_token。驗證令牌JWT在C#中使用JWK
不用說,我已經試過幾乎所有的東西,但(IdenityModels.Jwt等),但JwtSecurityTokenHandler不採取JsonWebKey。 我使用RS512作爲簽名算法。
我只是這個實現自己的谷歌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庫將不得不收拾x
,y
PARAMS自己,大概。