Authorize requests using external authorizer
This article shows an Azure API management policy sample that demonstrates how to secure API access by using an external authorizer encapsulating custom authentication/authorization logic. To set or edit a policy code, follow the steps described in Set or edit a policy. To see other examples, see policy samples.
Policy
Paste the code into the inbound block.
<!-- The policy defined in this file shows how to secure API access by using an external authorizer encapsulating custom authentication/authorization logic.
In this sample we assume that:
External authorizer evaluates only the information contained within the Authorization header. Alternatively, for example, a full copy of the incoming request can be forwarded to the authorizer by setting "mode" to copy in the send-request policy.
External authorizer URL is stored in a named value called "authorizer-url" and is secured with a key included in a query parameter.
External authorizer responds with a JSON object containing a property called "status" that is set to 200 if authorization was successful and 403 if it wasn't.
-->
<!-- Copy the following snippet into the inbound section and look at the trace window to see it work. -->
<policies>
<inbound>
<base/>
<!-- Ensure presence of Authorization header -->
<choose>
<when condition="@(!context.Request.Headers.ContainsKey("Authorization"))">
<return-response>
<set-status code="401" reason="Unauthorized" />
<set-header name="WWW-Authenticate" exists-action="append">
<value>@("Bearer realm="+context.Request.OriginalUrl.Host)</value>
</set-header>
</return-response>
</when>
</choose>
<!-- Check for cached authorization status for the subject -->
<cache-lookup-value key="@(context.Request.Headers.GetValueOrDefault("Authorization"))" variable-name="status"/>
<choose>
<!--
If a cache miss call external authorizer
-->
<when condition="@(!context.Variables.ContainsKey("status"))">
<!-- Invoke -->
<send-request mode="new" response-variable-name="response" timeout="10" ignore-error="false">
<set-url>{{authorizer-url}}</set-url>
<set-method>GET</set-method>
<set-header name="Authorization" exists-action="override">
<value>@(context.Request.Headers.GetValueOrDefault("Authorization"))</value>
</set-header>
</send-request>
<!-- Extract authorization status from authorizer's response -->
<set-variable name="status" value="@(((IResponse)context.Variables["response"]).Body.As<JObject>()["status"].ToString())"/>
<!-- Cache authorization result -->
<cache-store-value key="@(context.Request.Headers.GetValueOrDefault("Authorization"))" value="@((string)context.Variables["status"])" duration="5"/>
</when>
</choose>
<!-- Authorize the request -->
<choose>
<when condition="@((string)context.Variables["status"] == "403")">
<return-response>
<set-status code="403" reason="Forbidden" />
</return-response>
</when>
</choose>
</inbound>
<backend>
<base/>
</backend>
<outbound>
<base/>
</outbound>
</policies>
Next steps
Learn more about APIM policies:
Feedback
Submit and view feedback for