Extract JWT Claims in Azure API Management Policy

JSON Web Tokens (JWT) are easy to validate in Azure API Management (APIM) using policy statements. This makes integration with Azure Active Directory and other OpenID providers nearly foolproof. For example, one might add the following directive to the <inbound> policy for an API to ensure that the caller has attached a bearer token with acceptable audience, issuer and application ID values in the signed JWT:

  <openid-config url="https://login.windows.net/contoso.onmicrosoft.com/.well-known/openid-configuration" />
    <claim name="appid" match="all">

That’s nice. A little bit of markup and all that nasty security plumbing is handled outside the API. But what if we want to pass some individual claims named inside the token on to the API backend? Unfortunately, Azure APIM doesn’t have that built into JWT token validation policy. Ideally, we’d be able to extract claims during validation into variables and pass them in HTTP headers before the request is forwarded to the backing API. Until that feature is added, here’s how you can do that:

<set-header name="token-app-id" exists-action="override">
  string appId = "NOAUTH";
  string authHeader = context.Request.Headers.GetValueOrDefault("Authorization", "");
  if (authHeader?.Length > 0)
    string[] authHeaderParts = authHeader.Split(' ');
    if (authHeaderParts?.Length == 2 && authHeaderParts[0].Equals("Bearer", StringComparison.InvariantCultureIgnoreCase))
      Jwt jwt;
      if (authHeaderParts[1].TryParseJwt(out jwt))
        appId = jwt.Claims.GetValueOrDefault("appid", "NOAPPID");
    return appId;

In this code, I’ve added some script inside the <set-header> policy statement to fetch the Authorization header from the request, check that it’s a Bearer type token, attempt to parse it (which checks the token’s signature), then finally extracts the value of one specific claim. Most of that work already happens inside <validate-jwt> policy, as you can imagine. Until there’s an easier way to extract JWT claims individually, the solution shown here works nicely. Enjoy.

If you agree with me that this feature should be built right into the <validate-jwt> policy, please upvote the feature request I wrote on the APIM feedback site.

Leave a comment

Your email address will not be published.