Search code examples
azureoauth-2.0azure-active-directoryazure-api-managementazure-appservice

Use Azure App Service Authentication to log into Api Management Service


I was able to setup Azure Active Directory (aad) to authenticate users for the App Service running an angular front-end, now I want to secure the backend by allowing only this authenticated users to send requests to the Api Management Service endpoint.

So, I followed this article https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad and I am facing 2 major problems:

  1. The /.auth/me endpoint only returns an id_token, not an access_token
  2. When I try with postman, I keep on getting invalid audience, but postman uses an audience that looks like 00000-00000...

Here's the api management service inbound request policy jwt-validate:

<policies>
    <inbound>
        <base />
        <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="failed message">
            <openid-config url="https://login.microsoftonline.com/{tenant-id}/.well-known/openid-configuration" />
            <audiences>
                <audience>{app-id-uri}></audience>
            </audiences>
        </validate-jwt>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies> 

Solution

  • For your first problem:

    Actually, it can just response id token when you request the /.auth/me endpoint because you just implement login but not specify a resource(or a backend app/api protected by AD) in your app service. So the response contains id token and without access token.

    If you want to get access token when you request /.auth/me endpoint, you need to specify the resource in your app service. Here I assume you have already registered an app in Azure AD to represent your APIM. Then you can use the Resource Explore to modify the settings like below:

    1 . locate your app service

    2 . locate the config->authsettings (the resource below is the client id of the app you registered to represent your APIM)

    "additionalLoginParams": [
      "response_type=code id_token",
      "resource=3fa9607b-63cc-4050-82b7-91e44ff1df38"
    ],
    

    3 . config the redirect_uri for Azure app like below: https://yourapp.azurewebsites.net/.auth/login/aad/callback

    Then after you login in the angular app, you can get the access_token via the endpoint: https://yourapp.azurewebsites.net/.auth/me

    The steps above come from this post, you can also refer to it for detail information.

    For your second problem:

    When you request the APIM api in postman, you should put the access token in the request header. And you mentioned that the access token which you used in postman contains the audience like 00000-00000... But in your validate-jwt policy, you use:

    <audiences>
        <audience>{app-id-uri}</audience>
    </audiences>
    

    It seems {app-id-uri} is not only a id but should be a uri like: api://00000-00000.... So please change {app-id-uri} from uri format to id format (just remove api://).