0
votes

I am trying to create a policy in Azure APIM to validate JWT Tokens (Azure AD tokens) based on two different claims.

My API may be consumed by either other applications or users - it may be called from an user context or an application context. As such, the token might contain either the "scp" claim e.g. user_impersonation or "roles" claim like [ "CallApiAsAnApp" ].

From the documentation, I have not found any way to do this. Is this possible or do I have to implement custom code to do this at the API level? Any claims added to "required-claims" in the policy become mandatory. There doesn't seem to be any "match-any" option at the claims level, only values level.

2
Can this sample help you? I mean that if your request has some tags could be used to know whether to check roles or scp ?tiny-wa

2 Answers

0
votes

As you mentioned the token may contain either the scp cllaim or roles claim, it seems your token sometimes generated in "Delegated" type and sometimes generated in "Application" type. You just need to configure the <validate-jwt> policy like below screenshot, add both of the claims in it and choose "Any claim".

enter image description here

After that, the token can be validated if it just contain one claim.

By the way, please check if your tokens in two situations have same "Audiences", otherwise your requirement may not be implemented by the configuration above.

0
votes

In the end, the only way I could find to fix the issue is to use the choose element instead of validate-jwt, with custom code (which is what I was hoping to avoid any way). Basically I am saving the validated JWT Token to a variable and then using if / elseif to determine if the token is acceptable. Working relevant configuration below

<validate-jwt header-name="Authorization" failed-validation-httpcode="401" require-scheme="Bearer" output-token-variable-name="valid-jwt">
    <openid-config url="https://login.microsoftonline.com/tenantid/v2.0/.well-known/openid-configuration" />
    <issuers>
        <issuer>https://sts.windows.net/tenantid/</issuer>
    </issuers>
</validate-jwt>
<choose>
    <when condition="@{
        var jwt = (Jwt)context.Variables["valid-jwt"];
        if(jwt.Claims.ContainsKey("roles")){
            var roles = jwt.Claims["roles"];
            return !Array.Exists(roles, element => element == "MyRoleName");
        } else if (jwt.Claims.ContainsKey("scp")){
            var scp = jwt.Claims["scp"];
            return !Array.Exists(scp, element => element == "user_impersonation");
        } else { return true; }
    }">
<return-response>
    <set-status code="401" reason="Unauthorized" />
</return-response>
</when>
<otherwise />
</choose>