jjwt/README.md

193 lines
7.0 KiB
Markdown
Raw Normal View History

[![Build Status](https://travis-ci.org/jwtk/jjwt.svg?branch=master)](https://travis-ci.org/jwtk/jjwt)
2015-10-27 21:55:52 -04:00
[![Coverage Status](https://coveralls.io/repos/jwtk/jjwt/badge.svg?branch=master)](https://coveralls.io/r/jwtk/jjwt?branch=master)
2014-09-12 21:06:24 -04:00
2016-06-17 18:11:08 -04:00
## Java JWT: JSON Web Token for Java and Android
2014-09-18 22:14:22 -04:00
2014-09-25 16:52:02 -04:00
JJWT aims to be the easiest to use and understand library for creating and verifying JSON Web Tokens (JWTs) on the JVM.
2016-06-17 18:11:08 -04:00
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.
2014-09-25 16:49:59 -04:00
## Installation
Use your favorite Maven-compatible build tool to pull the dependency (and its transitive dependencies) from Maven Central:
Maven:
```xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
```
Gradle:
```groovy
dependencies {
compile 'io.jsonwebtoken:jjwt:0.6.0'
}
```
Note: JJWT depends on Jackson 2.x. If you're already using an older version of Jackson in your app, [read this](#olderJackson)
2016-06-17 18:11:08 -04:00
## 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:
2014-09-18 22:14:22 -04:00
2014-09-19 17:47:01 -04:00
```java
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.MacProvider;
import java.security.Key;
// We need a signing key, so we'll create one just for this example. Usually
// the key would be read from your application configuration instead.
2015-05-13 16:04:11 -04:00
Key key = MacProvider.generateKey();
2014-09-18 22:14:22 -04:00
2016-06-17 18:11:08 -04:00
String compactJws = Jwts.builder()
.setSubject("Joe")
.signWith(SignatureAlgorithm.HS512, key)
.compact();
2014-09-19 17:47:01 -04:00
```
2014-09-18 22:14:22 -04:00
How easy was that!?
2016-06-17 18:11:08 -04:00
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
```
2014-09-18 22:14:22 -04:00
Now let's verify the JWT (you should always discard JWTs that don't match an expected signature):
2014-09-19 17:47:01 -04:00
```java
2016-06-17 18:11:08 -04:00
assert Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws).getBody().getSubject().equals("Joe");
2014-09-19 17:47:01 -04:00
```
2014-09-18 22:14:22 -04:00
2016-06-17 18:11:08 -04:00
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!
2014-09-18 22:14:22 -04:00
But what if signature validation failed? You can catch `SignatureException` and react accordingly:
2014-09-19 17:47:01 -04:00
```java
try {
2014-09-18 22:14:22 -04:00
2016-06-17 18:11:08 -04:00
Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);
2014-09-18 22:14:22 -04:00
2014-09-19 17:47:01 -04:00
//OK, we can trust this JWT
2014-09-18 22:14:22 -04:00
2014-09-19 17:47:01 -04:00
} catch (SignatureException e) {
2014-09-18 22:14:22 -04:00
2014-09-19 17:47:01 -04:00
//don't trust the JWT!
}
```
2014-09-18 22:14:22 -04:00
## Supported Features
2016-06-17 18:11:08 -04:00
### Specification Compliant:
2014-09-19 17:30:47 -04:00
* Creating and parsing plaintext compact JWTs
2014-09-18 22:14:22 -04:00
* Creating, parsing and verifying digitally signed compact JWTs (aka JWSs) with all standard JWS algorithms:
2015-04-17 12:59:16 -04:00
* HS256: HMAC using SHA-256
2014-09-18 22:14:22 -04:00
* HS384: HMAC using SHA-384
* HS512: HMAC using SHA-512
* RS256: RSASSA-PKCS-v1_5 using SHA-256
* RS384: RSASSA-PKCS-v1_5 using SHA-384
* RS512: RSASSA-PKCS-v1_5 using SHA-512
* PS256: RSASSA-PSS using SHA-256 and MGF1 with SHA-256
* PS384: RSASSA-PSS using SHA-384 and MGF1 with SHA-384
* PS512: RSASSA-PSS using SHA-512 and MGF1 with SHA-512
* ES256: ECDSA using P-256 and SHA-256
* ES384: ECDSA using P-384 and SHA-384
* ES512: ECDSA using P-512 and SHA-512
2014-09-18 22:14:22 -04:00
2016-06-17 18:11:08 -04:00
### 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> 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
}
```
2014-09-18 22:14:22 -04:00
## Currently Unsupported Features
2014-09-25 16:43:41 -04:00
* [Non-compact](https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-7.2) serialization and parsing.
* JWE (Encryption for JWT)
2014-09-18 22:14:22 -04:00
2016-06-17 18:11:08 -04:00
These feature sets will be implemented in a future release. Community contributions are welcome!
## Learn More
- [JSON Web Token for Java and Android](https://stormpath.com/blog/jjwt-how-it-works-why/)
- [How to Create and Verify JWTs in Java](https://stormpath.com/blog/jwt-java-create-verify/)
- [Where to Store Your JWTs - Cookies vs HTML5 Web Storage](https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/)
- [Use JWT the Right Way!](https://stormpath.com/blog/jwt-the-right-way/)
- [Token Authentication for Java Applications](https://stormpath.com/blog/token-auth-for-java/)
2016-06-17 17:30:47 -04:00
- [JJWT Changelog](CHANGELOG.md)
<a name="olderJackson"></a>
#### Already using an older Jackson dependency?
JJWT depends on Jackson 2.4.x (or later). If you are already using a Jackson version in your own application less than 2.x, for example 1.9.x, you will likely see [runtime errors](https://github.com/jwtk/jjwt/issues/1). To avoid this, you should change your project build configuration to explicitly point to a 2.x version of Jackson. For example:
```xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.2</version>
</dependency>
```
## Author
Maintained by [Stormpath](https://stormpath.com/)
## Licensing
2016-06-17 18:11:08 -04:00
This project is open-source via the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).