Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure API Management : validate jwt token scope

We want to protect API operation call with the validate-jwt policy but I have an issue when I use the required-claims to check the scopes. Example : I have a token with a scope including several values like "xxx.READ xxx.WRITE yyy.READ yyy.WRITE ..." For a specific operation I want to use the validate-jwt policy to check if the token contains the scope linked like :

    <required-claims>
            <claim name="scp" match="any">
                <value>xxx.READ</value>
            </claim>
    </required-claims>

But the validation always fails because of the multiple values in the scp... How can I check this claim? Do I have to extract the scp values before and if yes how can I do that?

Thanks in advance

like image 545
Cedric G. Avatar asked Apr 05 '26 16:04

Cedric G.


1 Answers

Multi-value claims should be represented as arrays inside JWT token:

"scp": ["xxx.READ", "xxx.WRITE", "yyy.READ", "yyy.WRITE"]

this scenarios is completely supported with policy configuration that you've posted.

But if you represent them as a single string ("xxx.READ xxx.WRITE yyy.READ yyy.WRITE") then you have to use manual expressions to validate such token, something along these lines:

<choose>
    <when condition="@(context.Request.Headers.ContainsKey("Authorization"))">
        <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization", string.Empty).AsJwt())" />
        <choose>
            <when condition="@{
if (context.Variables["token"] == null) {
    return false;
}

var scp = ((Jwt)context.Variables["token"]).Claims.GetValueOrDefault("scp", (string[])null);
if (scp == null || scp.Length == 0) {
    return false;
}

return scp.Any(c => c.Contains("xxx.READ"));
            }">
                <return-response response-variable-name="existing response variable">
                    <set-status code="401" reason="Unauthorized" />
                </return-response>
            </when>
        </choose>
    </when>
    <otherwise>
        <return-response response-variable-name="existing response variable">
            <set-status code="401" reason="Unauthorized" />
        </return-response>
    </otherwise>
</choose>
like image 188
Vitaliy Kurokhtin Avatar answered Apr 08 '26 14:04

Vitaliy Kurokhtin