如何在Azure APIM中使用RS256算法生成JWT?
Azure APIM 基于RS256算法生成JWT实现方案
该需求完全可以通过APIM内置的策略表达式能力实现,不需要依赖外部服务,具体实现思路和操作指引如下:
实现前提
- 已持有标准PEM格式的PKCS#8 RS256私钥,以及符合JWT规范的header、payload内容
- 拥有APIM实例的策略编辑、命名值配置权限
操作步骤
- 第一步:存储私钥到APIM保密命名值
进入APIM实例→左侧导航栏选择「命名值」→点击「添加」,自定义名称(例如RS256-Private-Key),值填写完整的私钥内容,勾选「保密」选项后保存,避免私钥明文泄露。 - 第二步:配置APIM策略生成JWT
你可以根据业务需求,将生成逻辑配置在入站策略(请求后端前生成JWT携带转发)或出站策略(返回给调用方前生成JWT返回),参考策略示例如下:
<policies> <inbound> <base /> <!-- 读取保密存储的RS256私钥 --> <set-variable name="privateKey" value="{{RS256-Private-Key}}" /> <!-- 赋值JWT Header,若已有现成header可直接替换此处序列化逻辑 --> <set-variable name="jwtHeader" value="@{ var header = new { alg = "RS256", typ = "JWT" }; return JsonConvert.SerializeObject(header); }" /> <!-- 赋值JWT Payload,若已有现成payload可直接替换此处序列化逻辑 --> <set-variable name="jwtPayload" value="@{ var payload = new { iss = "your-custom-issuer", sub = "your-custom-subject", exp = DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeSeconds() }; return JsonConvert.SerializeObject(payload); }" /> <!-- 生成符合JWT规范的Base64Url编码Header --> <set-variable name="encodedHeader" value="@{ var bytes = System.Text.Encoding.UTF8.GetBytes((string)context.Variables["jwtHeader"]); return Convert.ToBase64String(bytes).TrimEnd('=').Replace('+', '-').Replace('/', '_'); }" /> <!-- 生成符合JWT规范的Base64Url编码Payload --> <set-variable name="encodedPayload" value="@{ var bytes = System.Text.Encoding.UTF8.GetBytes((string)context.Variables["jwtPayload"]); return Convert.ToBase64String(bytes).TrimEnd('=').Replace('+', '-').Replace('/', '_'); }" /> <!-- 用RS256算法生成签名并转Base64Url编码 --> <set-variable name="signature" value="@{ var signContent = $"{context.Variables["encodedHeader"]}.{context.Variables["encodedPayload"]}"; var signBytes = System.Text.Encoding.UTF8.GetBytes(signContent); using(var rsa = System.Security.Cryptography.RSA.Create()) { rsa.ImportFromPem((string)context.Variables["privateKey"]); var signResult = rsa.SignData(signBytes, System.Security.Cryptography.HashAlgorithmName.SHA256, System.Security.Cryptography.RSASignaturePadding.Pkcs1); return Convert.ToBase64String(signResult).TrimEnd('=').Replace('+', '-').Replace('/', '_'); } }" /> <!-- 拼接得到完整JWT --> <set-variable name="completeJwt" value="@{ return $"{context.Variables["encodedHeader"]}.{context.Variables["encodedPayload"]}.{context.Variables["signature"]}"; }" /> <!-- 示例:将生成的JWT放入Authorization头转发给后端服务 --> <set-header name="Authorization" exists-action="override"> <value>@($"Bearer {context.Variables["completeJwt"]}")</value> </set-header> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
注意事项
- 私钥安全:禁止将私钥明文硬编码在策略代码中,必须存储为保密类型的命名值,APIM会自动对保密命名值做加密存储。
- 编码规则:JWT要求使用Base64Url编码,不是普通Base64,必须完成替换特殊字符、去除末尾填充符的操作,否则会出现签名验证失败的问题。
- 格式校验:header中必须声明
alg: RS256、typ: JWT,payload建议添加exp过期时间字段,避免生成的JWT长期有效带来安全风险。 - 若你使用的APIM实例版本不支持
ImportFromPem方法,可先将私钥转换为PKCS#8格式的字节数组,使用ImportPkcs8PrivateKey方法导入即可。
内容的提问来源于stack exchange,提问作者senthil kumar
相关产品推荐
相关产品推荐

