Skip to content

Instantly share code, notes, and snippets.

@gregjbrown
Created October 27, 2022 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregjbrown/09c971695a8d3000ff1a1454725397d5 to your computer and use it in GitHub Desktop.
Save gregjbrown/09c971695a8d3000ff1a1454725397d5 to your computer and use it in GitHub Desktop.
Azure APIM policy.cshtml
<policies>
<inbound>
<base />
<set-variable name="requestId" value="@(context.RequestId)" />
<set-variable name="serviceName" value="@(context.Deployment.ServiceName)" />
<set-variable name="originalUrl" value="@(context.Request.OriginalUrl.ToString())" />
<set-variable name="authorization" value="@(context.Request.Headers.GetValueOrDefault("Authorization"))" />
<set-variable name="uriSegments" value="@(JsonConvert.SerializeObject(new Uri(context.Request.Url.ToString()).Segments))" />
<choose>
<when condition="@((bool)context.Request.HasBody)">
<set-variable name="requestBody" value="@(context.Request.Body.As<string>(preserveContent: true))" />
</when>
</choose>
<send-request mode="new" response-variable-name="response" timeout="10" ignore-error="false">
<set-url>{{opa-authorizer-url}}</set-url>
<set-method>POST</set-method>
<set-body template="liquid">
{
"input": {
"request": {
"headers": {
"host": "{{context.Request.Url.Host}}",
"authorization": "{{context.Variables["authorization"]}}"
},
"parsed_path": {{context.Variables["uriSegments"]}},
"path": "{{context.Request.Url.Path}}",
"port": "{{context.Request.Url.Port}}",
"scheme": "{{context.Request.Url.Scheme}}",
"query_string": "{{context.Request.Url.QueryString}}",
"url": "{{context.Request.Url.ToString}}",
"method": "{{context.Request.Method}}",
"request_id": "{{context.Variables["requestId"]}}"
{% if (context.Request.HasBody) %},
"body": {{context.Variables["requestBody"]}}
{% endif %}
},
"apim_name": "{{context.Variables["serviceName"]}}",
"original_url": "{{context.Variables["originalUrl"]}}"
}
}
</set-body>
</send-request>
<choose>
<!-- Return status code if non-200 status from OPA -->
<when condition="@(((IResponse)context.Variables["response"]).StatusCode != 200)">
<return-response>
<set-status code="@(((IResponse)context.Variables["response"]).StatusCode)" reason="@(((IResponse)context.Variables["response"]).StatusReason)" />
</return-response>
</when>
</choose>
<set-variable name="decisionJson" value="@(((IResponse)context.Variables["response"]).Body.As<JObject>())" />
<choose>
<!-- If result is not returned in response then request denied, return 403 -->
<when condition="@(!((JObject)context.Variables["decisionJson"]).ContainsKey("result"))">
<return-response>
<set-status code="403" reason="Forbidden" />
</return-response>
</when>
</choose>
<set-variable name="allow" value="@(((JObject)context.Variables["decisionJson"])["result"].ToString())" />
<choose>
<!-- If result is returned and not true then request denied, return 403 -->
<when condition="@(((string)context.Variables["allow"]).ToLower() != "true")">
<return-response>
<set-status code="403" reason="Forbidden" />
</return-response>
</when>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment