Extracting values from a JWT token in APIm

Extracting values from a JWT

If you know me, you know I like security, and sometimes security means being sneaky.

Why?

Recently we needed to identify the user of an incoming call in a backend function. Basically different rules should apply depending on which user was calling the API.

This API is protected using OAUTH 2.0 and as such has a JWT-token sent to it, and using this token is much more secure that simply using the subscription key. More secure since it implies that the caller has authenticated using your AAD.

How?

In the Token there is a property called Subject. This property is the immutable ObjectID of the calling client. This ID can be used to identify the caller.

The scenario called for the backend service to receive this ID as a header. You have to place the JWT extraction after the JWT validation. That way you do not only know you are dealing with a proper token before sending data to the backend system but the validation contains a way of surfacing the JWT token as a variable.

<validate-jwt header-name="Authorization" 
              failed-validation-httpcode="401"
              failed-validation-error-message="Token is invalid" 
              output-token-variable-name="jwt-token">
    <openid-config url="{{my-openid-configuration-url}}" />
    <audiences>
        <audience>{{myAudienceGUID}}</audience>
    </audiences>
    <issuers>
        <issuer>{{myIssuer}}</issuer>
    </issuers>
</validate-jwt>
<!-- Extract the subject and add it to a header -->
<set-header name="caller-objectid" exists-action="override">
    <value>@(((Jwt)context.Variables["jwt-token"]).Subject)</value>
</set-header>

There are some things to point out in this code.
On row 4: I name the output variable to jwt-token. This is how I access the token later.
On row 15: Be sure to override any attempts to set this header from the caller.
On row 16: You need to type the variable jwt-token as Jwt before accessing the property Subject.

More info

The official docs on Validate Jwt.
An official (not that great) example of using JWT values in a policy.

The Jwt class in APIm

It is kind of hard to find as you need to search for jwt on this page. So here they are:

**Algorithm**: string
**Audiences**: IEnumerable<string>
**Claims**: IReadOnlyDictionary<string, string[]>
**ExpirationTime**: DateTime?
**Id**: string
**Issuer**: string
IssuedAt: DateTime?
**NotBefore**: DateTime?
**Subject**: string
**Type**: string