Azure API Management(APIM)调用后端受保护API的凭证配置问题
Azure APIM自动附加后端API认证Token实现方案
方案1:使用APIM内置授权功能(即你提到的Authorization credentials)
该方案适合你的后端/auth/token接口为标准OAuth2密码授权模式的场景,无需编写自定义策略:
- 在APIM实例左侧导航栏找到「授权」菜单,点击「+ 创建」按钮
- 授权提供程序选择「通用OAuth 2.0」,自定义填写标识名称(如
Backend_Auth) - 授权类型选择「密码凭据(Password grant)」,按实际参数填写以下配置:
- 令牌端点:替换为你的实际接口地址
https://xxxx.com/api/v1/auth/token - 客户端ID/客户端密钥:如果你的token接口无要求可填任意占位符,有要求则填写对应有效值
- 用户名/密码:填写后端API可正常认证的账号密码
- 作用域:无特殊要求可留空
- 令牌端点:替换为你的实际接口地址
- 配置完成后保存,等待授权状态显示为「已连接」即可使用
- 最后在对应API的入站策略中添加
<authentication-authorization provider-id="Backend_Auth" identity="*" />即可自动完成token附加
方案2:自定义APIM策略实现(适合非标准认证接口场景,灵活度更高)
如果你的token接口有自定义参数或返回格式,可通过入站策略实现token的自动获取、缓存、附加:
核心逻辑
- 优先从缓存读取未过期的后端token,减少重复调用token接口的开销
- 缓存无有效token时自动调用
/auth/token接口获取新token,缓存有效期设置为比token实际过期时间短1-2分钟,避免边缘过期问题 - 所有转发到后端的请求自动添加
Authorization请求头
示例策略
可在API级别或全局级别配置如下入站策略,敏感参数建议提前存入APIM「命名值」中避免明文泄露:
<policies> <inbound> <base /> <!-- 保留你原有配置的AD OAuth2认证策略,确保合作方身份校验正常 --> <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized" require-expiration-time="true" require-scheme="Bearer"> <!-- 此处保留你原有AD认证的配置内容 --> </validate-jwt> <!-- 从缓存读取后端token --> <cache-lookup-value key="backend_bearer_token" variable-name="backendToken" /> <choose> <when condition="@(!context.Variables.ContainsKey("backendToken"))"> <!-- 调用后端token接口获取新凭证 --> <send-request mode="new" response-variable-name="tokenResponse" timeout="20" ignore-error="false"> <set-url>https://xxxx.com/api/v1/auth/token</set-url> <set-method>POST</set-method> <set-header name="Content-Type" exists-action="override"> <!-- 根据你的接口实际要求调整,如为JSON格式则改为application/json --> <value>application/x-www-form-urlencoded</value> </set-header> <set-body>@{ // 根据接口实际参数调整,此处为表单格式示例,JSON格式可直接写对应字符串 return $"username={{backend_username}}&password={{backend_password}}&grant_type=password"; }</set-body> </send-request> <!-- 解析返回的token信息 --> <set-variable name="accessToken" value="@(((IResponse)context.Variables["tokenResponse"]).Body.As<JObject>()["access_token"].ToString())" /> <set-variable name="expiresIn" value="@(((IResponse)context.Variables["tokenResponse"]).Body.As<JObject>()["expires_in"].ToObject<int>())" /> <!-- 写入缓存,有效期比token实际过期时间短2分钟 --> <cache-store-value key="backend_bearer_token" value="@((string)context.Variables["accessToken"])" duration="@((int)context.Variables["expiresIn"] - 120)" /> <set-variable name="backendToken" value="@((string)context.Variables["accessToken"])" /> </when> </choose> <!-- 给转发请求附加后端要求的认证头 --> <set-header name="Authorization" exists-action="override"> <value>@($"Bearer {(string)context.Variables["backendToken"]}")</value> </set-header> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
注意事项
- 确保APIM实例的出口IP已加入后端API的白名单,或APIM与后端API在同一VNet内可正常互通
- 所有占位参数(如账号、密码、AD认证配置等)请替换为你的实际有效值
内容的提问来源于stack exchange,提问作者Dean Yardley
相关产品推荐
相关产品推荐

