JJWT簡(jiǎn)介(翻譯)

Java JWT: JSON Web Token for Java and Android

JJWT的是在JVM上創(chuàng)建和驗(yàn)證JSON Web Token(JWTs)的庫(kù)。
JJWT是基于JWT、JWS、JWE、JWK和JWA RFC規(guī)范的Java實(shí)現(xiàn)。
這個(gè)庫(kù)是由Okta的Les Hazlewood創(chuàng)建的,現(xiàn)在由一個(gè)貢獻(xiàn)者社區(qū)維護(hù)。

什么是JSON Web Token

JWT是一種在兩方之間傳輸信息的方法。
在JWT的主體中編碼的信息被稱為claims。JWT的擴(kuò)展形式是JSON格式,因此每個(gè)claim都是JSON對(duì)象中的一個(gè)鍵。
JWTs可以加密簽名(使它成為JWS)或加密(使它成為JWE)。
這為JWTs增強(qiáng)了可驗(yàn)證性。例如,接收者可以確定JWT沒(méi)有通過(guò)驗(yàn)證簽名來(lái)篡改。
所生成JWT的結(jié)果是有三個(gè)部分的字符串,每個(gè)部分由"."分隔。
例如:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

每一節(jié)都是base 64編碼的。

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

eyJhbGciOiJIUzI1NiJ9

第二部分是body。本節(jié)包含了JWT編碼的所有聲明。

eyJzdWIiOiJKb2UifQ

最后一部分是signature。它通過(guò)在頭文件中指定的算法通過(guò)header和body的組合來(lái)計(jì)算。

ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

如果你通過(guò)一個(gè)基本的64解碼器傳遞前兩個(gè)部分,你將得到:

header

{
  "alg": "HS256"
}
body

{
  "sub": "Joe"
}

在這種情況下,我們得到的信息是使用sha - 256算法的HMAC來(lái)簽署JWT。而且,body有一個(gè)claim sub與value Joe。

Registered Claims 包含一些標(biāo)準(zhǔn)的claims,sub就是其中的一個(gè)(subject)。

要計(jì)算簽名,你必須知道簽名的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的老版本,你必須更新項(xiàng)目中的版本到新版本,否則會(huì)沖突。

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

快速使用

先看一個(gè)簡(jiǎn)單的例子:

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();

在上邊的例子中下,我們構(gòu)建了一個(gè)JWT,該JWT將將注冊(cè)的claim的sub(subject)設(shè)置為Joe,使用sha - 512算法在HMAC上注冊(cè)JWT。最后,我們將它轉(zhuǎn)換成字符串形式。

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJKb2UifQ.yiV1GWDrQyCeoOswYTf_xvlgsnaVVYJM0mU6rkmRBf2T1MBl3Xh2kZii0Q9BdX5-G0j25Qv2WF4lA6jPl5GKuA

下面來(lái)驗(yàn)證一下jwt:

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

這里有兩個(gè)時(shí)間。之前的密鑰被用來(lái)驗(yàn)證JWT的簽名。如果未能驗(yàn)證JWT,則拋出一個(gè)簽名異常。假設(shè)JWT已被驗(yàn)證,我們將解析claim并斷言該sub被設(shè)置為Joe。

但如果簽名驗(yàn)證失敗了怎么辦?可以捕獲簽名異常并做出相應(yīng)的反應(yīng):

try {

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

    //OK, we can trust this JWT

} catch (SignatureException e) {

    //don't trust the JWT!
}

支持的特性

兼容的規(guī)范

  • 創(chuàng)建和解析明文壓縮JWTs
  • 創(chuàng)建、解析和驗(yàn)證所有標(biāo)準(zhǔn)JWS算法的數(shù)字簽名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

增強(qiáng)的規(guī)范

  • body壓縮。如果JWT體大,可以使用壓縮解碼器來(lái)壓縮它。最重要的是,JJWT庫(kù)將自動(dòng)解壓并解析JWT,而不需要額外的編碼。
String compactJws =  Jwts.builder()
    .setSubject("Joe")
    .compressWith(CompressionCodecs.DEFLATE)
    .signWith(SignatureAlgorithm.HS512, key)
    .compact();

如果檢查Jws的header部分,它就會(huì)對(duì)這個(gè)進(jìn)行解碼:

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

JJWT自動(dòng)檢測(cè)到壓縮是通過(guò)檢查頭來(lái)使用的,并且在解析時(shí)將自動(dòng)解壓。對(duì)于解壓縮,不需要額外的編碼。

  • 要求claims。在解析時(shí),您可以指定某些斷言必須存在并設(shè)置為某個(gè)值。
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)是簽發(fā)該證書的負(fù)責(zé)人。

2. "sub" (Subject) Claim

"sub" (Subject)是主體。

3. "aud" (Audience) Claim

"aud" (Audience) Claim是指jwt的接受者,假如aud沒(méi)有發(fā)現(xiàn),則解析jwt時(shí)會(huì)拋出異常

4. "exp" (Expiration Time) Claim

"exp" (Expiration Time)指的是過(guò)期時(shí)間,假如超過(guò)過(guò)期時(shí)間,則會(huì)拋出異常

5. "nbf" (Not Before) Claim

"nbf" (Not Before) Claim指的是開(kāi)始日期,claim要求當(dāng)前日期/時(shí)間必須在以后或等于
在“nbf”聲明中列出的日期/時(shí)間

6. "iat" (Issued At) Claim

"iat" (Issued At) Claim是指jwt的發(fā)行時(shí)間

7. "jti" (JWT ID) Claim

"jti" (JWT ID) Claim為JWT提供了惟一的標(biāo)識(shí)符,如果應(yīng)用程序
使用多個(gè)發(fā)行者,必須在值之間避免沖突,
由不同的發(fā)行商制作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容