I am using Azure API Management to connect to an on-prem backend service (API) that is secured through Azure Active Directory. But in my setup both Azure Application Proxy + the backend service are in conflict because they both require, or claim, the Authorization http header.
The situation:
APIM => Application Proxy => Managed Identity => Backend service (API)
|--> requires Authorization: Bearer |
|
|--> also requires Authorization: Bearer
The problem is that both the backend service and App Proxy/Managed identity require the same http header; Authorization. When using managed identity, this http header field gets overwritten, or hijacked, by the App Proxy / Managed Identity.
Example from the trace logs:
authentication-managed-identity (0.577 ms)
{
"message": "Obtaining managed identity token using clientId:1139001d-75a0-451a-8fdc-14672baad4f4 AAD Authority:https://login.windows.net/e64eed3b-130b-4001-b50d-f867ed318682 for 1ca6a7dc-02e0-409c-aa39-c378cf0620db audience succeeded.",
"errorResponse": null
}
set-header (0.009 ms)
{
"message": "Specified value was assigned to the header (see below).",
"header": {
"name": "Authorization",
"value": "Bearer ...
}
Things I've tried:
- In APIM, attempt to overwrite the Authorization header in a
<backend>
policy; unfortunately, you cannot add additional backend policies in APIM (see this thread); - Haven't found anything the Azure docs ;
- It is not possible in the backend service to use a different http header name for Authorization;
An example of my APIM configuration:
<policies>
<inbound>
<base />
<!-- [required] fetch a token from Azure AD -->
<authentication-managed-identity resource="abc...123" client-id="def...456"
output-token-variable-name="msi-access-token" ignore-error="false" />
<!-- [required] inject the token in Authorization header, otherwise you need to login with AD first; this overwrite is the problem.
-->
<set-header name="Authorization" exists-action="override">
<value>@("Bearer " + (string)context.Variables["msi-access-token"])</value>
</set-header>
</inbound>
<backend>
<base />
<!-- cannot add additional policies here? -->
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
The question: is there a way to prevent the Authorization header being overwritten in this setup? Or differently put, deliver the original Authorization: Bearer
to the backend service?
Alternatively, is there a way to use a different means of authentication for App Proxy/Managed identity, instead of using the Authorization header (perhaps a different name, or through http body)?