2

I am having trouble accessing nested claims from a JWT using jose4j. I have a JWT whose claim set looks like this:

{
    "iss": "awesome.issuer",
    "iat": 1300819370,
    "exp": 1300819380,
    "clm": "string claim",
    "sub": "batman",
    "context": {
        "username": "mpdavis",
        "firstName": "Michael",
        "lastName": "Davis
    }
}

I am running into issues when I try to access and of the nested claims inside the context claim. I can access top level claims easily with the getClaimValue.

private String qsh;

qsh = jwtClaims.getClaimValue("qsh", String.class);

It seems like I have two options if I want to get a nested claim.

The first option is to find a way to return the context claim as a Map<String,Object> and pull each claim out of that object. The other option is to use flattenClaims to flatten all of the claims into a Map<String,List<Object>> and grab the first object off of the map for the nested claims.

Neither one of these options seem particularly resilient if the service granting these JWTs alters the schema very much.

Is there a better way?

Michael Davis
  • 2,350
  • 2
  • 21
  • 29

1 Answers1

3

That's about right.

You can get the claim value as a Map and access its content like this (or iterate on it).

@SuppressWarnings("unchecked")
Map<String,String> context = claims.getClaimValue("context", Map.class);
String username = context.get("username");
String firstName = context.get("firstName");

Using flattenClaims might look something like this:

Map<String,List<Object>> flattened = claims.flattenClaims();
String username = (String)flattened.get("context.username").iterator().next();
String firstName = (String)flattened.get("context.firstName").iterator().next();

Or you could iterate the whole thing and convert it to whatever data structure makes sense for your application.

You could likely make things more resilient to changes in the claims JSON with things like isClaimValueOfType(...) and hasClaim(...) and things like that on JwtClaims.

Or you can also use getRawJson() on JwtClaims and pass the JSON to the JSON processor of your choice, if you want.

Brian Campbell
  • 2,293
  • 12
  • 13