Search code examples
azureoauth-2.0authorizationazure-active-directoryazure-api-management

Validating Authorization token in incoming requests with Azure API management and third party Authorization Server


I have to implement OAuth 2.0 in my project with a third party Authorization Server. Both my client and server are already registered on the AS. I have created an API management instance on Azure and imported the swagger APIs. I want every incoming request to be validated against my AS, so I just need to redirect the request to https://my-as.com/as/introspect.oauth2, and have the token validated. If the token is valid then let it proceed or else send 401. I was trying to implement this using "inbound processing" and referred to the following doc: https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-protect-backend-with-aad#configure-a-jwt-validation-policy-to-pre-authorize-requests.

The only problem is that instead of Azure AD I'm using a third party AS. I tried replacing the URL in sample XML code with my URL, but its not working.

How do I redirect requests to the Authorization Server for validating access token?


Solution

  • Adding following inbound policy worked:

    <inbound>
            <!-- Extract Token from Authorization header parameter -->
            <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param").Split(' ').Last())" />
            <!-- Send request to Token Server to validate token (see RFC 7662) -->
            <send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true">
                <set-url>https://my-as.com/as/introspect.oauth2</set-url>
                <set-method>POST</set-method>
                <set-header name="Content-Type" exists-action="override">
                    <value>application/x-www-form-urlencoded</value>
                </set-header>
                <set-body>@($"grant_type=urn:pingidentity.com:oauth2:grant_type:validate_bearer&client_id=UoM&client_secret=somesecret&token={(string)context.Variables["token"]}")</set-body>
            </send-request>
            <choose>
                <!-- Check active property in response -->
                <when condition="@((bool)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["active"] == false)">
                    <!-- Return 401 Unauthorized with http-problem payload -->
                    <return-response response-variable-name="existing response variable">
                        <set-status code="401" reason="Unauthorized" />
                        <set-header name="WWW-Authenticate" exists-action="override">
                            <value>Bearer error="invalid_token"</value>
                        </set-header>
                    </return-response>
                </when>
            </choose>
            <base />
        </inbound>