JJWT简介(翻译)

Java JWT: JSON Web Token for Java and Android

JJWT的是在JVM上创建和验证JSON Web Token(JWTs)的库。
JJWT是基于JWT、JWS、JWE、JWK和JWA RFC规范的Java实现。
这个库是由Okta的Les Hazlewood创建的,现在由一个贡献者社区维护。

什么是JSON Web Token

JWT是一种在两方之间传输信息的方法。
在JWT的主体中编码的信息被称为claims。JWT的扩展形式是JSON格式,因此每个claim都是JSON对象中的一个键。
JWTs可以加密签名(使它成为JWS)或加密(使它成为JWE)。
这为JWTs增强了可验证性。例如,接收者可以确定JWT没有通过验证签名来篡改。
所生成JWT的结果是有三个部分的字符串,每个部分由"."分隔。
例如:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

每一节都是base 64编码的。

第一部分是header,必须指定用于签署JWT的算法。

eyJhbGciOiJIUzI1NiJ9

第二部分是body。本节包含了JWT编码的所有声明。

eyJzdWIiOiJKb2UifQ

最后一部分是signature。它通过在头文件中指定的算法通过header和body的组合来计算。

ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

如果你通过一个基本的64解码器传递前两个部分,你将得到:

header

{
  "alg": "HS256"
}
body

{
  "sub": "Joe"
}

在这种情况下,我们得到的信息是使用sha - 256算法的HMAC来签署JWT。而且,body有一个claim sub与value Joe。

Registered Claims 包含一些标准的claims,sub就是其中的一个(subject)。

要计算签名,你必须知道签名的sercrect。

安装

Maven:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

Gradle:

dependencies {
    compile 'io.jsonwebtoken:jjwt:0.9.0'
}

Note:JJWt依赖了 Jackson 2.x。
假如你依赖了jackson的老版本,你必须更新项目中的版本到新版本,否则会冲突。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.9</version>
</dependency>

快速使用

先看一个简单的例子:

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.
Key key = MacProvider.generateKey();

String compactJws = Jwts.builder()
  .setSubject("Joe")
  .signWith(SignatureAlgorithm.HS512, key)
  .compact();

在上边的例子中下,我们构建了一个JWT,该JWT将将注册的claim的sub(subject)设置为Joe,使用sha - 512算法在HMAC上注册JWT。最后,我们将它转换成字符串形式。

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJKb2UifQ.yiV1GWDrQyCeoOswYTf_xvlgsnaVVYJM0mU6rkmRBf2T1MBl3Xh2kZii0Q9BdX5-G0j25Qv2WF4lA6jPl5GKuA

下面来验证一下jwt:

assert Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws).getBody().getSubject().equals("Joe");

这里有两个时间。之前的密钥被用来验证JWT的签名。如果未能验证JWT,则抛出一个签名异常。假设JWT已被验证,我们将解析claim并断言该sub被设置为Joe。

但如果签名验证失败了怎么办?可以捕获签名异常并做出相应的反应:

try {

    Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);

    //OK, we can trust this JWT

} catch (SignatureException e) {

    //don't trust the JWT!
}

支持的特性

兼容的规范

  • 创建和解析明文压缩JWTs
  • 创建、解析和验证所有标准JWS算法的数字签名JWTs(又称JWSs):
  • HS256: HMAC using SHA-256
  • 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-521 and SHA-512

增强的规范

  • body压缩。如果JWT体大,可以使用压缩解码器来压缩它。最重要的是,JJWT库将自动解压并解析JWT,而不需要额外的编码。
String compactJws =  Jwts.builder()
    .setSubject("Joe")
    .compressWith(CompressionCodecs.DEFLATE)
    .signWith(SignatureAlgorithm.HS512, key)
    .compact();

如果检查Jws的header部分,它就会对这个进行解码:

{
  "alg": "HS512",
  "zip": "DEF"
}

JJWT自动检测到压缩是通过检查头来使用的,并且在解析时将自动解压。对于解压缩,不需要额外的编码。

  • 要求claims。在解析时,您可以指定某些断言必须存在并设置为某个值。
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 e) {

    // we get here if the required claim has the wrong value

}

Registered Claim

所有的claim是可选的,并且是大小写敏感的。

1. "iss" (Issuer) Claim

"iss" (issuer)是签发该证书的负责人。

2. "sub" (Subject) Claim

"sub" (Subject)是主体。

3. "aud" (Audience) Claim

"aud" (Audience) Claim是指jwt的接受者,假如aud没有发现,则解析jwt时会抛出异常

4. "exp" (Expiration Time) Claim

"exp" (Expiration Time)指的是过期时间,假如超过过期时间,则会抛出异常

5. "nbf" (Not Before) Claim

"nbf" (Not Before) Claim指的是开始日期,claim要求当前日期/时间必须在以后或等于
在“nbf”声明中列出的日期/时间

6. "iat" (Issued At) Claim

"iat" (Issued At) Claim是指jwt的发行时间

7. "jti" (JWT ID) Claim

"jti" (JWT ID) Claim为JWT提供了惟一的标识符,如果应用程序
使用多个发行者,必须在值之间避免冲突,
由不同的发行商制作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 175,490评论 5 419
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 74,060评论 2 335
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 124,407评论 0 291
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 47,741评论 0 248
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 56,543评论 3 329
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 43,040评论 1 246
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 34,107评论 3 358
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 32,646评论 0 229
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 36,694评论 1 271
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 32,398评论 2 279
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 33,987评论 1 288
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 30,097评论 3 285
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 35,298评论 3 282
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 27,278评论 0 14
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 28,413评论 1 232
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 38,397评论 2 309
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 38,099评论 2 314

推荐阅读更多精彩内容