Azure Apim:外部 Beckend API Oauth2 身份验证与 Bearer 令牌集成
Azure Apim : External Beckend API Oauth2 authentication with Bearer token integration
我们目前的情况:
- 在 Azure API 管理器中,我们基于 Swagger 定义构建了一些 APIs。
- API 的提供者向我们提供了客户端 ID 和密码。
- 其中一些 API 调用需要使用承载令牌进行身份验证,承载令牌是在提供商的 API 基础设施上生成的,具有上述 /token 端点,我们希望集成身份验证流程这些 API 在 APIM 中调用(因为前端将以另一种方式进行身份验证(可能是 CORS))
- 我们尝试了各种方法,在 APIM 设置中使用“OAuth2.0”服务配置的各种变体,并将它们应用于 API 定义,我们一直收到未经授权的 401。
作为起点,我们使用 https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad,但我们发现的大多数解释都与使用 AD 有关,据我们了解,我们不需要它。
我们尝试将以下 OAuth 2.0 Postman 授权配置实施到 APIM(实际上在 Postman 中有效)。
是否有一种简单直接的方法告诉 APIM 使用给定的 ClientId 和密码调用令牌 URL 并添加授权 header不记名令牌到后端 API?
是的 - 你可以这样做,这里是一个遵循类似过程的 Curity resource:
- 根据传入的凭据发出 OAuth 请求以获取 JWT
- 转发给下游API
- 缓存具有相同传入凭据的后续请求的结果
您的情况略有不同,但使用相同的构建块。您只需调整 OAuth 消息即可使用客户端凭据流。
感谢 Gary 为我指明了正确的方向。我对这个话题还很陌生,所以我的方法可能远非完美,但它确实有效。
我最终修改了 API 调用的入站策略并添加了以下内容(将 xxxx 替换为适当的设置)
<policies>
<inbound>
//....
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true">
<set-url>https://xxxxxxxxxx.azurewebsites.net/connect/token</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>*.*</value>
</set-header>
<set-body>
@("grant_type=client_credentials&scope=xxxxxx&client_id=xxxxxxxx&client_secret=xx")
</set-body>
</send-request>
<set-variable name="bearerToken" value="@(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["access_token"].ToString())" />
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["bearerToken"])</value>
</set-header>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>*/*</value>
</set-header>
</inbound>
简短说明
- 发起新请求,响应将存储在变量(令牌状态)中
- 方法定义为POST
- Headers 已设置请求(Centent-Type & 接受)
- 请求的body已定义
由于令牌请求的响应(存储在 tokenstate 中)是 JSON 格式的,请求的响应被转换为 JObject 并且“access_token”是存储在“bearerToken”变量中(或者你可以不分配变量并立即将此行放在下一步中。
设置“Autorization”header 值为“Bearer”+ [bearerToken]
额外的步骤(设置 header Content-Type & 接受)我需要能够调试,但在正常情况下,它们将由 API 的请求客户端添加.
我们目前的情况:
- 在 Azure API 管理器中,我们基于 Swagger 定义构建了一些 APIs。
- API 的提供者向我们提供了客户端 ID 和密码。
- 其中一些 API 调用需要使用承载令牌进行身份验证,承载令牌是在提供商的 API 基础设施上生成的,具有上述 /token 端点,我们希望集成身份验证流程这些 API 在 APIM 中调用(因为前端将以另一种方式进行身份验证(可能是 CORS))
- 我们尝试了各种方法,在 APIM 设置中使用“OAuth2.0”服务配置的各种变体,并将它们应用于 API 定义,我们一直收到未经授权的 401。
作为起点,我们使用 https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad,但我们发现的大多数解释都与使用 AD 有关,据我们了解,我们不需要它。
我们尝试将以下 OAuth 2.0 Postman 授权配置实施到 APIM(实际上在 Postman 中有效)。
是否有一种简单直接的方法告诉 APIM 使用给定的 ClientId 和密码调用令牌 URL 并添加授权 header不记名令牌到后端 API?
是的 - 你可以这样做,这里是一个遵循类似过程的 Curity resource:
- 根据传入的凭据发出 OAuth 请求以获取 JWT
- 转发给下游API
- 缓存具有相同传入凭据的后续请求的结果
您的情况略有不同,但使用相同的构建块。您只需调整 OAuth 消息即可使用客户端凭据流。
感谢 Gary 为我指明了正确的方向。我对这个话题还很陌生,所以我的方法可能远非完美,但它确实有效。
我最终修改了 API 调用的入站策略并添加了以下内容(将 xxxx 替换为适当的设置)
<policies>
<inbound>
//....
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true">
<set-url>https://xxxxxxxxxx.azurewebsites.net/connect/token</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>*.*</value>
</set-header>
<set-body>
@("grant_type=client_credentials&scope=xxxxxx&client_id=xxxxxxxx&client_secret=xx")
</set-body>
</send-request>
<set-variable name="bearerToken" value="@(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["access_token"].ToString())" />
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["bearerToken"])</value>
</set-header>
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-header name="Accept" exists-action="override">
<value>*/*</value>
</set-header>
</inbound>
简短说明
- 发起新请求,响应将存储在变量(令牌状态)中
- 方法定义为POST
- Headers 已设置请求(Centent-Type & 接受)
- 请求的body已定义
由于令牌请求的响应(存储在 tokenstate 中)是 JSON 格式的,请求的响应被转换为 JObject 并且“access_token”是存储在“bearerToken”变量中(或者你可以不分配变量并立即将此行放在下一步中。
设置“Autorization”header 值为“Bearer”+ [bearerToken]
额外的步骤(设置 header Content-Type & 接受)我需要能够调试,但在正常情况下,它们将由 API 的请求客户端添加.