Search code examples
azureazure-api-managementapim

How do I conditionally restrict API Endpoint Access based on Audience ID?


I have an API imported in the Azure API Manager that contains several endpoints. I need to define a policy within APIM that will allow one Audience ID to access all endpoints within the API while a second audience ID can only access 2 of the endpoints and are denied access to the rest of the endpoints.

First I've tried playing around with the 'Match="Any"' option within required-claims of the inbound section of the policy but I can't find a way to perform an -and function ( If aud=XXX AND this endpoint....)

Second, I tried using the "Choose" function within the outbound section but can't quite figure out how to reference the audience IDs, if it's even possible.

Lastly, all the googling and self research have lead to either dead ends or info beyond my skillset.

TIA,


Solution

  • You should be able to do it with a combination of choose, when and otherwise. The following assumes that your client-presented JWT has an aud claim, which will then be addressed using jwt_claims["aud"] after token validation.

    The AND operator in a condition statement is represented by &&, and OR is ||, just like in C#.

    <policies>
        <inbound>
            <base />
            <!-- Validate JWT Token -->
            <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Invalid or expired token." require-exp="true" require-scheme="Bearer" require-signed-tokens="true">
                <audiences>
                    <audience>aud1</audience>
                    <audience>aud2</audience>
                </audiences>
                <issuers>
                    <!-- Add your JWT token issuer here -->
                    <issuer>https://your-issuer.com/</issuer>
                </issuers>
                <keys>
                    <!-- Add your JWT token keys here -->
                    <key>
                        <certificate>PASTE-TOKEN-SIGNING-PUBLIC-KEY-HERE</certificate>
                    </key>
                </keys>
            </validate-jwt>
            <!-- Define policy logic to check for audience and endpoint access -->
            <choose>
                <when condition="@(jwt_claims['aud'] == 'aud1')">
                    <!-- Allow aud1 access to all endpoints -->
                    <base />
                </when>
                <when condition="@(jwt_claims['aud'] == 'aud2')">
                    <choose>
                        <when condition="@(context.Request.MatchedRoute.Path.Value == "/endpoint1" || context.Request.MatchedRoute.Path.Value == "/endpoint2")">
                            <!-- Allow access to specific endpoints for aud2 -->
                            <base />
                        </when>
                        <otherwise>
                            <!-- Deny access to other endpoints for aud2 -->
                            <return-response>
                                <set-status code="403" reason="Forbidden" />
                            </return-response>
                        </otherwise>
                    </choose>
                </when>
                <otherwise>
                    <!-- Deny access if audience ID is not recognized -->
                    <return-response>
                        <set-status code="403" reason="Forbidden" />
                    </return-response>
                </otherwise>
            </choose>
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>
    

    Update the policy with appropriate values for the audience claim name, audience IDs, token issuer, token signing public key, API endpoints, and you should be good to go.