Azure API管理:使用OAuth保护网关和后端之间的连接?
我们有一个受标准OAuth凭据流保护的现有后端。我们正在移动所有流量以通过Azure API网关,并找到了使用OAuth的以下策略(来源:)Azure API管理:使用OAuth保护网关和后端之间的连接?,azure,oauth,azure-api-management,Azure,Oauth,Azure Api Management,我们有一个受标准OAuth凭据流保护的现有后端。我们正在移动所有流量以通过Azure API网关,并找到了使用OAuth的以下策略(来源:) {{authorizationServer}} 邮递 应用程序/x-www-form-urlencoded @{ 返回“client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_凭证”; } @((Bearer“+(String)(
{{authorizationServer}}
邮递
应用程序/x-www-form-urlencoded
@{
返回“client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_凭证”;
}
@((Bearer“+(String)((IResponse)context.Variables[“bearerToken”]).Body.As()[“access_token”])
但是,该策略似乎没有重用令牌,因此每次调用都会获取一个新令牌。这不是最佳的,主要是因为性能,但也因为我们与Auth0的协议对这些调用的数量有限制
在网关和后端之间进行调用时,是否有办法重用令牌(如果它仍然有效)?尝试使用缓存存储值和缓存获取值将令牌存储在缓存中。若您事先检查令牌,您可以将int放入缓存,其过期时间为ttl。只要确保有一个后备逻辑,以防缓存的令牌不起作用 并没有简单的方法重用策略,所以重试部分可能看起来很麻烦。但只有当您想重试对缓存令牌的401响应的调用时,才需要这样做
<policies>
<inbound>
<base />
<cache-lookup-value key="bearerToken" variable-name="bearerToken" />
<choose>
<when condition="@(!context.Variables.ContainsKey("bearerToken"))">
<send-request ignore-error="true" timeout="20" response-variable-name="bearerToken" mode="new">
<set-url>{{authorizationServer}}</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-body>@("client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_credentials")</set-body>
</send-request>
<set-variable name="bearerToken" value="@((string)((IResponse)context.Variables["bearerToken"]).Body.As<JObject>()["access_token"])" />
<cache-store-value key="bearerToken" value="@((string)context.Variables["bearerToken"])" duration="60" />
<set-variable name="cachedToken" value="@(false)" />
</when>
<otherwise>
<set-variable name="cachedToken" value="@(true)" />
</otherwise>
</choose>
<!-- Don't expose APIM subscription key to the backend. -->
<set-header exists-action="delete" name="Ocp-Apim-Subscription-Key"/>
</inbound>
<backend>
<retry condition="@((bool)context.Variables["cachedToken"] && context.Response.StatusCode == 401)" count="1" interval="0" first-fast-retry="true">
<choose>
<when condition="@(context.Response.StatusCode == 401)">
<send-request ignore-error="true" timeout="20" response-variable-name="bearerToken" mode="new">
<set-url>{{authorizationServer}}</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-body>@("client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_credentials")</set-body>
</send-request>
<set-variable name="bearerToken" value="@((string)((IResponse)context.Variables["bearerToken"]).Body.As<JObject>()["access_token"])" />
<cache-store-value key="bearerToken" value="@((string)context.Variables["bearerToken"])" duration="60" />
<set-variable name="cachedToken" value="@(false)" />
</when>
</choose>
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["bearerToken"])</value>
</set-header>
<forward-request />
</retry>
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
{{authorizationServer}}
邮递
应用程序/x-www-form-urlencoded
@(“客户端id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_凭证”)
{{authorizationServer}}
邮递
应用程序/x-www-form-urlencoded
@(“客户端id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_凭证”)
@(“Bearer”+(string)context.Variables[“bearerToken”])
最干净、最简单的方法如下,它还利用“expires\u in”设置缓存持续时间:
<policies>
<inbound>
<base />
<cache-lookup-value key="cachedToken" variable-name="access_token" />
<choose>
<when condition="@(!context.Variables.ContainsKey("access_token"))">
<send-request ignore-error="true" timeout="20" response-variable-name="response" mode="new">
<set-url>{{authorizationServer}}</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-body>@("client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_credentials")</set-body>
</send-request>
<set-variable name="responseObject" value="@(((IResponse)context.Variables["response"]).Body.As<JObject>())" />
<set-variable name="access_token" value="@((string)((JObject)context.Variables["responseObject"])["access_token"])" />
<set-variable name="expires_in" value="@((int)((JObject)context.Variables["responseObject"])["expires_in"])" />
<cache-store-value key="cachedToken" value="@((string)context.Variables["access_token"])" duration="@(((int)context.Variables["expires_in"]) - 10)" />
</when>
</choose>
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["access_token"])</value>
</set-header>
<!-- Don't expose APIM subscription key to the backend. -->
<set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
{{authorizationServer}}
邮递
应用程序/x-www-form-urlencoded
@(“客户端id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_凭证”)
@(“载体”+(字符串)上下文变量[“访问令牌”])
非常感谢您的提示。您是否有一个完整的回退逻辑示例?用xml编码并不是我的强项。非常感谢。这正是我要找的。
<policies>
<inbound>
<base />
<cache-lookup-value key="cachedToken" variable-name="access_token" />
<choose>
<when condition="@(!context.Variables.ContainsKey("access_token"))">
<send-request ignore-error="true" timeout="20" response-variable-name="response" mode="new">
<set-url>{{authorizationServer}}</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-body>@("client_id={{clientId}}&resource={{scope}}&client_secret={{clientSecret}}&grant_type=client_credentials")</set-body>
</send-request>
<set-variable name="responseObject" value="@(((IResponse)context.Variables["response"]).Body.As<JObject>())" />
<set-variable name="access_token" value="@((string)((JObject)context.Variables["responseObject"])["access_token"])" />
<set-variable name="expires_in" value="@((int)((JObject)context.Variables["responseObject"])["expires_in"])" />
<cache-store-value key="cachedToken" value="@((string)context.Variables["access_token"])" duration="@(((int)context.Variables["expires_in"]) - 10)" />
</when>
</choose>
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["access_token"])</value>
</set-header>
<!-- Don't expose APIM subscription key to the backend. -->
<set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>