当我们升级到.net core 8.0 时,KeyVaultCryptoProvider.Create 方法失败

问题描述 投票:0回答:1

我们有以下代码片段,用于使用 Azure KeyVault 密钥生成令牌。 .net core 6.0 和 .net core 8.0 使用相同的方法。

public string GenerateJwtToken(DateTime expiryDateTime, Microsoft.IdentityModel.Tokens.SecurityKey securityKey) 
{ 
    SigningCredentials signingCredentials = new SigningCredentials(securityKey,SecurityAlgorithms.RsaSha256) 
    { 
    CryptoProviderFactory = new CryptoProviderFactory { CustomCryptoProvider = new Microsoft.IdentityModel.KeyVaultExtensions.KeyVaultCryptoProvider() } };

    SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
    {
        IssuedAt = DateTime.UtcNow,
        Expires = expiryDateTime,
        SigningCredentials = signingCredentials
    };
    
    string token = new JsonWebTokenHandler().CreateToken(tokenDescriptor);    
    return token;
}

在.net core 6.0中,它可以正常工作,没有任何错误,但在8.0中它会抛出以下错误。

System.MethodAccessException: Attempt by method 'Microsoft.IdentityModel.KeyVaultExtensions.KeyVaultCryptoProvider.Create(System.String, System.Object[])' to access method 'Microsoft.IdentityModel.Tokens.CryptoProviderFactory.ShouldCacheSignatureProvider(Microsoft.IdentityModel.Tokens.SignatureProvider)' failed.
         at Microsoft.IdentityModel.KeyVaultExtensions.KeyVaultCryptoProvider.Create(String algorithm, Object[] args)
         at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures, Boolean cacheProvider)
         at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm, Boolean cacheProvider)
         at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateForSigning(SecurityKey key, String algorithm)
         at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateSignature(ReadOnlySpan`1 data, Span`1 destination, SigningCredentials signingCredentials, Int32& bytesWritten)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.CreateToken(SecurityTokenDescriptor tokenDescriptor, Boolean setdefaultTimesOnTokenCreation, Int32 tokenLifetimeInMinutes)
         at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.CreateToken(SecurityTokenDescriptor tokenDescriptor)

我们尝试了使用 JwtSecurityToken 和 JwtSecurityTokenHandler().WriteToken(token) 生成密钥的不同方法。下面是结果,我们结束了

System.Security.Cryptography.CryptographicException:未知错误(0xc100000d) 在 System.Security.Cryptography.RSABCrypt.TrySignHash(ReadOnlySpan

1 hash, Span
1 目的地,HashAlgorithmName hashAlgorithm,RSASignaturePadding 填充,Int32& bytesWritten) 在 System.Security.Cryptography.RSA.SignHash(ReadOnlySpan
1 hash, Span
1 目的地,HashAlgorithmName hashAlgorithm,RSASignaturePadding 填充) 在 System.Security.Cryptography.RSABCrypt.SignHash(Byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding 填充) 在 Microsoft.IdentityModel.Tokens.AmetryAdapter.SignRsa(Byte[] 字节) 在 Microsoft.IdentityModel.Tokens.AmetryAdapter.Sign(Byte[] 字节) 在 Microsoft.IdentityModel.Tokens.AmetrySignatureProvider.Sign(Byte[] 输入) 在 Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(字符串输入,SigningCredentials 签名Credentials) 在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken 令牌)

使用的代码片段在这里

        SigningCredentials signingCredentials = new SigningCredentials(new RsaSecurityKey(new Azure.Security.KeyVault.Keys.Key.ToRSA()), SecurityAlgorithms.RsaSha256);

        JwtSecurityToken token = new JwtSecurityToken(claims: claims, signingCredentials: signingCredentials);

        return new JwtSecurityTokenHandler().WriteToken(token);

我需要一些帮助来减轻这个版本的混乱。

如果需要更多详细信息,请告诉我。 请注意:所有必需的库都已更新到最新的可用版本。

cryptography c#-8.0 identitymodel
1个回答
0
投票

问题解决了。当您从 Azure KeyVault 检索 KeyVaultKey 值时,同时创建 CryptographyClient。

keyClient = new(vaultUri: new Uri(keyVaultUri), credential: new DefaultAzureCredential(new DefaultAzureCredentialOptions()
                {
                    AdditionallyAllowedTenants = { tenatId }
                }));

cryptoClient = new CryptographyClient(keyClient.GetKey(keyName).Value.Id, new DefaultAzureCredential(new DefaultAzureCredentialOptions()
                {
                    AdditionallyAllowedTenants = { tenatId }
                }));

然后在逻辑方面使用下面

JwtSecurityToken token = new(claims: claims, notBefore: iat, expires: expiryDateTime, signingCredentials: new SigningCredentials(new RsaSecurityKey(adminSettings.PRDCryptoClient.CreateRSA()), SecurityAlgorithms.RsaSha256));

return new JwtSecurityTokenHandler().WriteToken(token);

这解决了问题。但我认为微软必须解决库问题才能回到之前的“SecurityKey”基于类的方法。

© www.soinside.com 2019 - 2024. All rights reserved.