Respect explicit set of null claims

Issue #252 resolved
Josu Vergara created an issue

Hi,

We are currently using JWTClaimsSet the following way:

 JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
 builder.claim("myclaim", null);
 [...]

However the JSON representation does not include myclaim, I would expect the payload to include the following attribute since it has been set explicitly:

{ "myclaim" : null }

The fix is trivial in the implementation of JWTClaimsSet.toJSONObject as far as I can see. Is there any good reason not to do this? I have not found anything in the specification that prevents this. I know that it looks minor, but we have a client that is expecting the custom claim to be set, so it is a requirement for us.

Comments (9)

  1. Josu Vergara reporter

    Hi @vdzhuvinov

    Thanks for the quick answer. Unfortunately, I get an authentication error when I try to create a branch in the project (I use both my ID and email to try to authenticate). I am attaching a fix proposal.

  2. Vladimir Dzhuvinov

    Hi,

    Branching within the repo works if you're team member. Forking the repo, and applying modes there, should work.

    I'm going to suggest you a work around for now. I found out that the builder pattern is often used by people with null values, who expect that if a claim happens to be null, it won't be output at all.

  3. Vladimir Dzhuvinov

    Check out the JWT example from commit 98e9993:

                   JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .subject("alice")
                .claim("myclaim", null)
                .build();
    
            JWSObject jwsObject = new JWSObject(
                new JWSHeader(JWSAlgorithm.HS256),
                new Payload(claimsSet.toJSONObject(true))
            );
    
            jwsObject.sign(new MACSigner(secret));
    
            SignedJWT jwt = SignedJWT.parse(jwsObject.serialize());
            assertTrue(jwt.verify(new MACVerifier(secret)));
    
            claimsSet = jwt.getJWTClaimsSet();
            assertEquals("alice", claimsSet.getSubject());
            assertNull(claimsSet.getClaim("myclaim"));
            assertTrue(claimsSet.getClaims().containsKey("myclaim"));
            assertEquals(2, claimsSet.getClaims().size());
    

    If it works for you, I'll cut out a new 5.6 release with the optional toJSONObject(boolean) method.

  4. Vladimir Dzhuvinov

    Note that SignedJWT extends JWSObject, the latter includes support for arbitrary payloads, which then allows the output JSON object to be included. For the recipient the serialisation is all the same.

  5. Josu Vergara reporter

    hi @vdzhuvinov

    Thanks again for the quick answer. After giving it a thought, it works for us. Thanks!

  6. Vladimir Dzhuvinov

    Great, the base JWS / JWE classes saved the day :)

    I just pushed the change as v5.6 to Maven Central. Should appear there later today. Happy coding!

  7. Log in to comment