如何通过Azure API Management中转调用OAuth 1.0认证的外部API?
在Azure API Management中处理OAuth 1.0认证(无需重复写复杂代码)
APIM确实没有原生支持OAuth 1.0的内置组件,但你可以通过自定义策略把签名逻辑封装在APIM里,让Logic Apps和Function Apps只需要调用APIM端点,不用自己处理认证。以下是具体实现方式:
步骤1:在APIM中存储OAuth 1.0密钥
先把你的consumer key、consumer secret、token id、token secret存到APIM的命名值里:
- 登录APIM控制台,进入“命名值”菜单
- 创建四个命名值,分别命名为
oauth-consumer-key、oauth-consumer-secret、oauth-token-id、oauth-token-secret - 对应填入你的密钥,勾选“保密”选项避免明文泄露
步骤2:添加自定义入站策略
把下面的策略代码添加到目标API的入站策略中(如果多个API都需要,也可以加到全局策略),这个策略会自动生成OAuth 1.0所需的签名和Authorization头:
<policies> <inbound> <base /> <!-- 生成OAuth所需的时间戳和随机串 --> <set-variable name="oauth_timestamp" value="@(DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())" /> <set-variable name="oauth_nonce" value="@(Guid.NewGuid().ToString("N"))" /> <set-variable name="oauth_signature_method" value="HMAC-SHA1" /> <set-variable name="oauth_version" value="1.0" /> <!-- 从命名值读取密钥 --> <set-variable name="consumer_key" value="{{oauth-consumer-key}}" /> <set-variable name="consumer_secret" value="{{oauth-consumer-secret}}" /> <set-variable name="token_id" value="{{oauth-token-id}}" /> <set-variable name="token_secret" value="{{oauth-token-secret}}" /> <!-- 构造签名基串 --> <set-variable name="signature_base_string" value="@( string.Format("{0}&{1}&{2}", context.Request.Method.ToUpper(), Uri.EscapeDataString(context.Request.Url.ToString()), Uri.EscapeDataString(string.Format( "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}", (string)context.Variables["consumer_key"], (string)context.Variables["oauth_nonce"], (string)context.Variables["oauth_signature_method"], (string)context.Variables["oauth_timestamp"], (string)context.Variables["token_id"], (string)context.Variables["oauth_version"] )) ) )" /> <!-- 生成签名密钥 --> <set-variable name="signing_key" value="@( string.Format("{0}&{1}", Uri.EscapeDataString((string)context.Variables["consumer_secret"]), Uri.EscapeDataString((string)context.Variables["token_secret"]) ) )" /> <!-- 计算HMAC-SHA1签名并Base64编码 --> <set-variable name="oauth_signature" value="@( Convert.ToBase64String( System.Security.Cryptography.HMACSHA1.Create().ComputeHash( System.Text.Encoding.ASCII.GetBytes((string)context.Variables["signature_base_string"]) ) ) )" /> <!-- 构造Authorization头,如果需要realm,在里面添加`oauth_realm="你的realm值"` --> <set-header name="Authorization" exists-action="override"> <value>@( string.Format( "OAuth oauth_consumer_key=\"{0}\", oauth_nonce=\"{1}\", oauth_signature=\"{2}\", oauth_signature_method=\"{3}\", oauth_timestamp=\"{4}\", oauth_token=\"{5}\", oauth_version=\"{6}\"", (string)context.Variables["consumer_key"], (string)context.Variables["oauth_nonce"], Uri.EscapeDataString((string)context.Variables["oauth_signature"]), (string)context.Variables["oauth_signature_method"], (string)context.Variables["oauth_timestamp"], (string)context.Variables["token_id"], (string)context.Variables["oauth_version"] ) )</value> </set-header> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
步骤3:测试和使用
现在你的Logic Apps和Function Apps只需要调用APIM暴露的API端点,APIM会自动完成OAuth 1.0的签名和认证,中转请求到外部API。
特殊情况处理
如果外部API使用的是PLAINTEXT签名方法(不推荐,但部分遗留系统支持),可以简化签名逻辑:直接把oauth_signature设置为{consumer_secret}&{token_secret}的URL编码值,省去HMAC计算的步骤。
内容的提问来源于stack exchange,提问作者Killianti
相关产品推荐
相关产品推荐

