使用 azure Apim 调用使用 OAuth2 令牌的 Api
Use azure Apim to Call an Api that uses OAuth2 token
使用 Apim,我正在尝试调用需要 OAuth2 验证的后端 Api。这个问题或多或少与此类似:Azure API Management: Oauth2 with backend API
但是这里没有好的答案...
我已经阅读了很多有关策略和缓存的内容。
但似乎无法正确设置。我希望能够调用 apim,然后 apim 调用后端 api 来获取令牌,并使用该令牌调用 Api 来获取一些输出数据。
我还发现了一个我必须在后端部分设置一些策略的地方..
谁能帮我制定政策?
我的政策是这样的:
<policies>
<inbound>
<base />
<set-variable name="originBearer" value="@(context.Request.Headers.GetValueOrDefault("Authorization", "empty_token").Split(' ')[0].ToString())" />
<send-request ignore-error="true" timeout="20" response-variable-name="bearerToken" mode="new">
<set-url>{{lookupAccessTokenUrl}}</set-url>
<set-method>GET</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@{
return "client_id={{HLR-app-client-id}}&scope={{HLR-scope}}&client_secret={{HLR-secret}}&assertion="+(string)context.Variables["originBearer"]+"&grant_type=urn:ietf:params:oauth:grant-type:client_credentials&requested_token_use=on_behalf_of";
}</set-body>
</send-request>
<set-variable name="requestResponseToken" value="@((String)((IResponse)context.Variables["bearerToken"]).Body.As<JObject>()["access_token"])" />
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["requestResponseToken"])</value>
</set-header>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
我找到了我自己的问题的答案:-)
我尝试在每一行上发表评论,但是如果你把所有代码放在一起,你就会得到一个在后端处理 Oauth2 的策略 api.
在入境部分,cache-lookup-value
将缓存中的值分配给名为“bearerToken”的上下文变量。
第一次进入时,缓存值将为空,变量不会
已创建。
<inbound>
<cache-lookup-value key="cacheAccessToken" variable-name="bearerToken" />
创建一个包含 clientid 和 secret 的变量 - 需要调用 api
<set-variable name="user-password" value="{{HLR-Clientid}}:{{HLR-Secret}}"
/>
<choose>
检查上下文变量 collection 是否包含名为
“bearerToken”,如果找不到则执行打开和关闭之间的代码
“”XML个元素。
<when condition="@(!context.Variables.ContainsKey("bearerToken"))">
发起对 OAuth 端点的请求和响应
超时 20 秒。这会将响应消息放入变量中
称为“oauthResponse”
<send-request mode="new" response-variable-name="oauthResponse" timeout="20" ignore-error="false">
<set-url>{{lookupAccessTokenUrl}}</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
在这里你定义你的header授权并使用包含clientid和密码的变量
<set-header name="Authorization" exists-action="override">
<value>@("Basic " + system.Convert.ToBase64String(Encoding.UTF8.GetBytes((string)context.Variables["user-password"])))</value>
</set-header>
<set-body>@("grant_type=client_credentials&scope={{HLR-Scope}}")</set-body>
</send-request>
将响应转换为 JSON object 以允许使用索引器检索“access_token”值并将其分配给上下文变量“accessToken”。
<set-variable name="AccessToken" value="@((string)((IResponse)context.Variables["oauthResponse"]).Body.As<JObject>()["access_token"])" />
将结果存储在缓存中,我们将变量“accessToken”的内容添加到缓存中 3600 秒。
<cache-store-value key="cacheAccessToken" value="@((string)context.Variables["AccessToken"])" duration="3600" />
将变量设置在context-variable中,即可使用
<set-variable name="bearerToken" value="@((string)context.Variables["AccessToken"])" />
</when>
</choose>
<base />
</inbound>
<backend>
<!--Creates the request to the backend web service. Here we are placing the response from the web service into the variable called “transferWSResponse”.-->
<send-request mode="copy" response-variable-name="transferWSResponse" timeout="60" ignore-error="false">
<set-method>GET</set-method>
<!--Is the creating the “Authorization” header to be sent with the request.-->
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["bearerToken"])</value>
</set-header>
<!--Removes the APIM subscription from being forwarded to the backend web service.-->
<set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
</send-request>
</backend>
<outbound>
<!--Now we need to return the response message from the backend web service to the caller. This is done in the “<outbound>” policy section. Here we just simply return the value of the variable “transferWSResponse” back to the caller-->
<return-response response-variable-name="transferWSResponse" />
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
使用 Apim,我正在尝试调用需要 OAuth2 验证的后端 Api。这个问题或多或少与此类似:Azure API Management: Oauth2 with backend API 但是这里没有好的答案...
我已经阅读了很多有关策略和缓存的内容。 但似乎无法正确设置。我希望能够调用 apim,然后 apim 调用后端 api 来获取令牌,并使用该令牌调用 Api 来获取一些输出数据。 我还发现了一个我必须在后端部分设置一些策略的地方.. 谁能帮我制定政策?
我的政策是这样的:
<policies>
<inbound>
<base />
<set-variable name="originBearer" value="@(context.Request.Headers.GetValueOrDefault("Authorization", "empty_token").Split(' ')[0].ToString())" />
<send-request ignore-error="true" timeout="20" response-variable-name="bearerToken" mode="new">
<set-url>{{lookupAccessTokenUrl}}</set-url>
<set-method>GET</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@{
return "client_id={{HLR-app-client-id}}&scope={{HLR-scope}}&client_secret={{HLR-secret}}&assertion="+(string)context.Variables["originBearer"]+"&grant_type=urn:ietf:params:oauth:grant-type:client_credentials&requested_token_use=on_behalf_of";
}</set-body>
</send-request>
<set-variable name="requestResponseToken" value="@((String)((IResponse)context.Variables["bearerToken"]).Body.As<JObject>()["access_token"])" />
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["requestResponseToken"])</value>
</set-header>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
我找到了我自己的问题的答案:-) 我尝试在每一行上发表评论,但是如果你把所有代码放在一起,你就会得到一个在后端处理 Oauth2 的策略 api.
在入境部分,cache-lookup-value 将缓存中的值分配给名为“bearerToken”的上下文变量。 第一次进入时,缓存值将为空,变量不会 已创建。
<inbound>
<cache-lookup-value key="cacheAccessToken" variable-name="bearerToken" />
创建一个包含 clientid 和 secret 的变量 - 需要调用 api
<set-variable name="user-password" value="{{HLR-Clientid}}:{{HLR-Secret}}"
/>
<choose>
检查上下文变量 collection 是否包含名为 “bearerToken”,如果找不到则执行打开和关闭之间的代码 “”XML个元素。
<when condition="@(!context.Variables.ContainsKey("bearerToken"))">
发起对 OAuth 端点的请求和响应 超时 20 秒。这会将响应消息放入变量中 称为“oauthResponse”
<send-request mode="new" response-variable-name="oauthResponse" timeout="20" ignore-error="false">
<set-url>{{lookupAccessTokenUrl}}</set-url>
<set-method>POST</set-method>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
在这里你定义你的header授权并使用包含clientid和密码的变量
<set-header name="Authorization" exists-action="override">
<value>@("Basic " + system.Convert.ToBase64String(Encoding.UTF8.GetBytes((string)context.Variables["user-password"])))</value>
</set-header>
<set-body>@("grant_type=client_credentials&scope={{HLR-Scope}}")</set-body>
</send-request>
将响应转换为 JSON object 以允许使用索引器检索“access_token”值并将其分配给上下文变量“accessToken”。
<set-variable name="AccessToken" value="@((string)((IResponse)context.Variables["oauthResponse"]).Body.As<JObject>()["access_token"])" />
将结果存储在缓存中,我们将变量“accessToken”的内容添加到缓存中 3600 秒。
<cache-store-value key="cacheAccessToken" value="@((string)context.Variables["AccessToken"])" duration="3600" />
将变量设置在context-variable中,即可使用
<set-variable name="bearerToken" value="@((string)context.Variables["AccessToken"])" />
</when>
</choose>
<base />
</inbound>
<backend>
<!--Creates the request to the backend web service. Here we are placing the response from the web service into the variable called “transferWSResponse”.-->
<send-request mode="copy" response-variable-name="transferWSResponse" timeout="60" ignore-error="false">
<set-method>GET</set-method>
<!--Is the creating the “Authorization” header to be sent with the request.-->
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["bearerToken"])</value>
</set-header>
<!--Removes the APIM subscription from being forwarded to the backend web service.-->
<set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
</send-request>
</backend>
<outbound>
<!--Now we need to return the response message from the backend web service to the caller. This is done in the “<outbound>” policy section. Here we just simply return the value of the variable “transferWSResponse” back to the caller-->
<return-response response-variable-name="transferWSResponse" />
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>