Regression: JWTClaimsSet including null values by default

Issue #549 resolved
Niall Couse created an issue

I am building JWTs using the JWTClaimsSet.Builder

For some fields they get set to null, where I don’t have a value for them.

Until now this worked, but as of 9.38 my JWTs have null claims, when I decode the serialised JWTs. Previously any null values would not be added to the claims list.

This seemed to happen between 9.38-rc5 and the 9.38 release. Looking at commits, it seems to have be introduced by feature: https://bitbucket.org/connect2id/nimbus-jose-jwt/issues/519/support-null-valued-jwt-claims

While I understand this feature is required, this is a change in default behaviour, that was not expected.

Comments (7)

  1. Niall Couse reporter

    While I normally use SignedJWT, here is the simplest code to demonstate this with PlainJWT.

            JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer("issuer").notBeforeTime(null).build();
    
            String jwt = new PlainJWT(jwtClaimsSet).serialize();
    

    If I decode the serialised JWT on 9.38, I get:

    {
      "iss": "issuer",
      "nbf": null
    }
    

    On 9.37.3 and before, I get:

    {
      "iss": "issuer"
    }
    

  2. Yavor Vasilev

    We didn’t have a good idea how to make this change & give people the choice to output / or not nulls.

    Any ideas, if you’re familiar with the JWTClaimsSet.Builder API?

  3. Niall Couse reporter

    The big problem is that this is a regression - I had code that was setting the claim based on a value that was passed in, and was allowed to be null, since this worked. In many cases it was null.

    After I upgraded the library, I noticed these null fields on my JWTs, which I was initially very confused by.

    This is a similar issue to say Jackson, where it can serialise JSON with or without nulls.

    For example, Jackson allows you to configure the serialiser to ignore values set to null (or not). You can also configure that per class with annotations.

    I don’t know the intricacies of the API, as the very basic API has been sufficient for my needs.

    Perhaps you can add configuration to JWTClaimsSet with options for serialisation, or on the JWT serialisation itself.

  4. Vladimir Dzhuvinov
    • changed status to open

    We spent some time analysing the API and will try adding a config to serialise null claims.

    It remains to figure out how to change the current behaviour of the `toJSONObject' methods.

        /**
         * Returns the JSON object representation of this claims set. The
         * claims are serialised according to their insertion order. Claims
         * with {@code null} values are not output.
         *
         * @return The JSON object representation.
         */
        public Map<String, Object> toJSONObject() {
    
            return toJSONObject(false);
        }
    
    
        /**
         * Returns the JSON object representation of this claims set. The
         * claims are serialised according to their insertion order.
         *
         * @param includeClaimsWithNullValues If {@code true} claims with
         *                                    {@code null} values will also be
         *                                    output.
         *
         * @return The JSON object representation.
         */
        public Map<String, Object> toJSONObject(final boolean includeClaimsWithNullValues) 
    
  5. Vladimir Dzhuvinov
    version 9.40 (2024-06-06)
        * New JWTClaimsSet.Builder.serializeNullClaims(boolean) method to control
          the serialisation of claims with null values when
          JWTClaimsSet.toPayload(), JWTClaimsSet.toJSONObject() or
          JWTClaimsSet.toString() is called. The serialisation to claims with null
          values is disabled by default. Note that with serializeNullClaims(true)
          the previous behaviour of JWTClaimsSet.toPayload(),
          JWTClaimsSet.toJSONObject() and JWTClaimsSet.toString() will no longer
          apply and claims will null values will be serialised.
        * Fixes regression, JWTClaimsSet.Builder.build() must not by default
          serialise claims with null values (iss #549).
    

  6. Log in to comment