简体   繁体   English

如何在 Azure API 管理策略表达式中使用 RSA SHA256 签署 JWT?

[英]How can I sign a JWT with RSA SHA256 in an Azure API Management Policy Expression?

In an Azure API Management Policy Expression I need to create a JWT signed with a private key.Azure API 管理策略表达式中,我需要创建一个使用私钥签名的 JWT。

When I try to use RSACryptoServiceProvider - just to check whether this feedback already got resolved - I get this error when trying to save the policy:当我尝试使用RSACryptoServiceProvider - 只是为了检查此反馈是否已得到解决 - 在尝试保存策略时出现此错误:

Usage of type 'System.Security.Cryptography.RSACryptoServiceProvider' is not supported within expressions 

Following a hint from maxim-kim , I tried RSA.Create() and to convert from this tutorial根据maxim-kim的提示,我尝试了 RSA.Create() 并从本教程转换

var privateKey = "whatever";
RSA rsa = RSA.Create();
rsa.ImportRSAPrivateKey(privateKey, out _);

var signingCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256)
{
    CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false }
};

var now = DateTime.Now;
var unixTimeSeconds = new DateTimeOffset(now).ToUnixTimeSeconds();

var jwt = new JwtSecurityToken(
    audience: _settings.Audience,
    issuer: _settings.Issuer,
    claims: new Claim[] {
        new Claim(JwtRegisteredClaimNames.Iat, unixTimeSeconds.ToString(), ClaimValueTypes.Integer64),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        new Claim(nameof(claims.FirstName), claims.FirstName),
        new Claim(nameof(claims.LastName), claims.LastName),
        new Claim(nameof(claims.Email), claims.Email)
    },
    notBefore: now,
    expires: now.AddMinutes(30),
    signingCredentials: signingCredentials
);

string token = new JwtSecurityTokenHandler().WriteToken(jwt);

return new JwtResponse
{
    Token = token,
    ExpiresAt = unixTimeSeconds,
};

but got the next error:但得到了下一个错误:

'RSA' does not contain a definition for 'ImportRSAPrivateKey' and no extension method 'ImportRSAPrivateKey' accepting a first argument of type 'RSA' could be found (are you missing a using directive or an assembly reference?)

So my question: Is there a way to create a signed JWT in an Azure API Management Policy Expression ?所以我的问题是:有没有办法在Azure API 管理策略表达式中创建签名的 JWT?

RSA initialization based on dynamically resolved private and public keys is not supported today.目前不支持基于动态解析的私钥和公钥的 RSA 初始化。 If RSA parameters are not request specific you can upload x509 certificate to APIM containing required RSA parameters and use it within expressions: using (var rsa = context.Deployment.Certificates["thumbprint"].GetRSAPrivateKey()) { .... }如果 RSA 参数不是特定于请求的,您可以将 x509 证书上传到包含所需 RSA 参数的 APIM 并在表达式中使用它: using (var rsa = context.Deployment.Certificates["thumbprint"].GetRSAPrivateKey()) { .... }

Thanks to this and other articles, I managed to sign in an APIM policy.感谢这篇文章和其他文章,我成功地登录了 APIM 策略。 Therefore I would like to share this.因此,我想分享这个。

    <set-variable name="signedPayload" value="@{
        using (RSA rsa = context.Deployment.Certificates["thumbprint"].GetRSAPrivateKey())
        {
            long unixTimeStampInSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();
            string header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; 
            string claimset = String.Format("{{ \"scope\": \"https://www.googleapis.com/auth/devstorage.read_write\", \"aud\": \"https://oauth2.googleapis.com/token\", \"iss\": \"blahblah.gserviceaccount.com\", \"iat\": {0}, \"exp\": {1} }}", unixTimeStampInSeconds, unixTimeStampInSeconds + 3599);
            string payload = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(header)) + "." + System.Convert.ToBase64String(Encoding.UTF8.GetBytes(claimset));
            byte[] signature = rsa.SignData(Encoding.UTF8.GetBytes(payload), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            return System.Net.WebUtility.UrlEncode(payload + "." + System.Convert.ToBase64String(signature));
        }
    }" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM