diff --git a/README.md b/README.md index 7fa465b8..0d349112 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ [![Build Status](https://travis-ci.org/jwtk/jjwt.svg?branch=master)](https://travis-ci.org/jwtk/jjwt) [![Coverage Status](https://coveralls.io/repos/jwtk/jjwt/badge.svg?branch=master)](https://coveralls.io/r/jwtk/jjwt?branch=master) -# Java JWT: JSON Web Token for Java and Android +## Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand library for creating and verifying JSON Web Tokens (JWTs) on the JVM. -JJWT is a 'clean room' implementation based solely on the [JWT](https://tools.ietf.org/html/rfc7519), [JWS](https://tools.ietf.org/html/rfc7515), [JWE](https://tools.ietf.org/html/rfc7516), [JWK](https://tools.ietf.org/html/rfc7517) and [JWA](https://tools.ietf.org/html/rfc7518) RFC specifications. +JJWT is an implementation based on the [JWT](https://tools.ietf.org/html/rfc7519), [JWS](https://tools.ietf.org/html/rfc7515), [JWE](https://tools.ietf.org/html/rfc7516), [JWK](https://tools.ietf.org/html/rfc7517) and [JWA](https://tools.ietf.org/html/rfc7518) RFC specifications. + +The library was created by [Stormpath's](http://www.stormpath.com) CTO, [Les Hazlewood](https://github.com/lhazlewood) +and is now maintained by a [community](https://github.com/jwtk/jjwt/graphs/contributors) of contributors. + +We've also added some convenience extensions that are not part of the specification, such as JWT compression and claim enforcement. ## Installation @@ -31,7 +36,7 @@ dependencies { Note: JJWT depends on Jackson 2.x. If you're already using an older version of Jackson in your app, [read this](#olderJackson) -## Usage +## Quickstart Most complexity is hidden behind a convenient and readable builder-based [fluent interface](http://en.wikipedia.org/wiki/Fluent_interface), great for relying on IDE auto-completion to write code quickly. Here's an example: @@ -45,25 +50,38 @@ import java.security.Key; // the key would be read from your application configuration instead. Key key = MacProvider.generateKey(); -String s = Jwts.builder().setSubject("Joe").signWith(SignatureAlgorithm.HS512, key).compact(); +String compactJws = Jwts.builder() + .setSubject("Joe") + .signWith(SignatureAlgorithm.HS512, key) + .compact(); ``` How easy was that!? +In this case, we are *building* a JWT that will have the [registered claim](https://tools.ietf.org/html/rfc7519#section-4.1) `sub` (subject) set to `Joe`. We are signing the JWT using the HMAC using SHA-512 algorithm. finally, we are compacting it into its `String` form. + +The resultant `String` looks like this: + +``` +eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJKb2UifQ.yiV1GWDrQyCeoOswYTf_xvlgsnaVVYJM0mU6rkmRBf2T1MBl3Xh2kZii0Q9BdX5-G0j25Qv2WF4lA6jPl5GKuA +``` + Now let's verify the JWT (you should always discard JWTs that don't match an expected signature): ```java -assert Jwts.parser().setSigningKey(key).parseClaimsJws(s).getBody().getSubject().equals("Joe"); +assert Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws).getBody().getSubject().equals("Joe"); ``` -You have to love one-line code snippets! +There are two things going on here. The `key` from before is being used to validate the signature of the JWT. If it fails to verify the JWT, a `SignatureException` is thrown. Assuming the JWT is validated, we parse out the claims and assert that that subject is set to `Joe`. + +You have to love code one-liners that pack a punch! But what if signature validation failed? You can catch `SignatureException` and react accordingly: ```java try { - Jwts.parser().setSigningKey(key).parseClaimsJws(compactJwt); + Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws); //OK, we can trust this JWT @@ -75,6 +93,8 @@ try { ## Supported Features +### Specification Compliant: + * Creating and parsing plaintext compact JWTs * Creating, parsing and verifying digitally signed compact JWTs (aka JWSs) with all standard JWS algorithms: @@ -91,12 +111,55 @@ try { * ES384: ECDSA using P-384 and SHA-384 * ES512: ECDSA using P-512 and SHA-512 +### Enhancements Beyond the Specification: + +* Body compression. If the JWT body is large, you can use a `CompressionCodec` to compress it. Best of all, the JJWT library will automtically decompress and parse the JWT without additional coding. + +```java +String compactJws = Jwts.builder() + .setSubject("Joe") + .compressWith(CompressionCodecs.DEFLATE) + .signWith(SignatureAlgorithm.HS512, key) + .compact(); +``` + +If you examine the header section of the `compactJws`, it decodes to this: + +``` +{ + "alg": "HS512", + "zip": "DEF" +} +``` + +JJWT automatically detects that compression was used by examining the header and will automatically decompress when parsing. No extra coding is needed on your part for decompression. + +* Require Claims. When parsing, you can specify that certain calims *must* be present and set to a certain value. + +```java +try { + Jws claims = Jwts.parser() + .requireSubject("Joe") + .require("hasMotorcycle", true) + .setSigningKey(key) + .parseClaimsJws(compactJws); +} catch (MissingClaimException e) { + + // we get here if the required claim is not present + +} catch (IncorrectClaimException) { + + // we get here if ther required claim has the wrong value + +} +``` + ## Currently Unsupported Features * [Non-compact](https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-7.2) serialization and parsing. * JWE (Encryption for JWT) -These feature sets will be implemented in a future release when possible. Community contributions are welcome! +These feature sets will be implemented in a future release. Community contributions are welcome! ## Learn More @@ -126,4 +189,4 @@ Maintained by [Stormpath](https://stormpath.com/) ## Licensing -This project is open-source via the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). \ No newline at end of file +This project is open-source via the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).