jjwt v0.6.0 Release Notes

  • ๐Ÿ“œ Enforce JWT Claims when Parsing

    ๐Ÿ“œ You can now enforce that JWT claims have expected values when parsing a compact JWT string.

    ๐Ÿ“œ For example, let's say that you require that the JWT you are parsing has a specific sub (subject) value, ๐Ÿ— otherwise you may not trust the token. You can do that by using one of the require methods on the parser builder:

    try {
        Jwts.parser().requireSubject("jsmith").setSigningKey(key).parseClaimsJws(s);
    } catch(InvalidClaimException ice) {
        // the sub field was missing or did not have a 'jsmith' value
    }
    

    If it is important to react to a missing vs an incorrect value, instead of catching InvalidClaimException, you can catch either MissingClaimException or IncorrectClaimException:

    try {
        Jwts.parser().requireSubject("jsmith").setSigningKey(key).parseClaimsJws(s);
    } catch(MissingClaimException mce) {
        // the parsed JWT did not have the sub field
    } catch(IncorrectClaimException ice) {
        // the parsed JWT had a sub field, but its value was not equal to 'jsmith'
    }
    

    You can also require custom fields by using the require(fieldName, requiredFieldValue) method - for example:

    try {
        Jwts.parser().require("myfield", "myRequiredValue").setSigningKey(key).parseClaimsJws(s);
    } catch(InvalidClaimException ice) {
        // the 'myfield' field was missing or did not have a 'myRequiredValue' value
    }
    

    (or, again, you could catch either MissingClaimException or IncorrectClaimException instead)

    Body Compression

    This feature is NOT JWT specification compliant, but it can be very useful when you parse your own tokens.

    ๐Ÿ’ป If your JWT body is large and you have size restrictions (for example, if embedding a JWT in a URL and the URL must be under a certain length for legacy browsers or mail user agents), you may now compress the JWT body using a CompressionCodec:

    Jwts.builder().claim("foo", "someReallyLongDataString...")
        .compressWith(CompressionCodecs.DEFLATE) // or CompressionCodecs.GZIP
        .signWith(SignatureAlgorithm.HS256, key)
        .compact();
    

    ๐Ÿ‘€ This will set a new zip header with the name of the compression algorithm used so that parsers can see that value and decompress accordingly.

    0๏ธโƒฃ The default parser implementation will automatically decompress DEFLATE or GZIP compressed bodies, so you don't need to set anything on the parser - it looks like normal:

    Jwts.parser().setSigningKey(key).parseClaimsJws(compact);
    
    Custom Compression Algorithms

    ๐Ÿ“œ If the DEFLATE or GZIP algorithms are not sufficient for your needs, you can specify your own Compression algorithms by implementing the CompressionCodec interface and setting it on the parser:

    Jwts.builder().claim("foo", "someReallyLongDataString...")
        .compressWith(new MyCompressionCodec())
        .signWith(SignatureAlgorithm.HS256, key)
        .compact();
    

    ๐Ÿ“œ You will then need to specify a CompressionCodecResolver on the parser, so you can inspect the zip header and return your custom codec when discovered:

    Jwts.parser().setSigningKey(key)
        .setCompressionCodecResolver(new MyCustomCompressionCodecResolver())
        .parseClaimsJws(compact);
    

    NOTE: Because body compression is not JWT specification compliant, you should only enable compression if both your JWT builder and parser are JJWT versions >= 0.6.0, or if you're using another library that implements the exact same functionality. This feature is best reserved for your own use cases - where you both create and later parse the tokens. It will likely cause problems if you compressed a token and expected a 3rd party (who doesn't use JJWT) to parse the token.