0

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

Juliën
  • 9,047
  • 7
  • 49
  • 80
  • Are you trying to pass through the incoming authorization header to the backend ? I mean if the original request has a valid token to call the backend API, you don't need to do anything. – Thomas Jun 22 '22 at 11:20
  • @Thomas Indeed. However, the App Proxy requires the same Authorization header as well. See the [docs on Authenticate with managed identity](https://learn.microsoft.com/en-us/azure/api-management/api-management-authentication-policies#use-managed-identity-and-set-header-manually). Otherwise I would indeed not to bother with the custom ``. – Juliën Jun 22 '22 at 13:25
  • You can only have one auth token, it make sense for me. What you probably want to do is validate the user token at APIM (throw 401 if invalid) then on your backend side you need to validate the managed identity APIM token. – Thomas Jun 22 '22 at 19:04

0 Answers0