Alternative to Azure Application Proxy requiring the Authorization header, in Azure APIM

491 Views Asked by At

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)?

0

There are 0 best solutions below