prepare 5.7.0

This commit is contained in:
Looly
2021-06-10 17:04:16 +08:00
parent 8080093ba5
commit f07a452e3a
34 changed files with 46 additions and 38 deletions

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>cn.hutool</groupId>
<artifactId>hutool-parent</artifactId>
<version>5.6.8-SNAPSHOT</version>
<version>5.7.0-SNAPSHOT</version>
</parent>
<artifactId>hutool-jwt</artifactId>

View File

@@ -0,0 +1,45 @@
package cn.hutool.jwt;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
import java.io.Serializable;
/**
* Claims 认证简单的JSONObject包装
*
* @author looly
*/
public class Claims implements Serializable {
private static final long serialVersionUID = 1L;
private final JSONObject claimJSON;
public Claims() {
this.claimJSON = new JSONObject();
}
/**
* 增加Claims属性如果属性值为{@code null},则移除这个属性
*
* @param name 属性名
* @param value 属性值
*/
protected void setClaim(String name, Object value) {
Assert.notNull(name, "Name must be not null!");
if (value == null) {
claimJSON.remove(name);
return;
}
claimJSON.set(name, value);
}
/**
* 获取Claims的JSON字符串形式
*
* @return JSON字符串
*/
public String getClaimsJson() {
return this.claimJSON.toString();
}
}

View File

@@ -0,0 +1,77 @@
package cn.hutool.jwt;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.signers.JWTSigner;
import java.nio.charset.Charset;
/**
* JSON Web Token (JWT)基于JSON的开放标准(RFC 7519)用于在网络应用环境间传递声明。<br>
* <p>
* 结构xxxxx.yyyyy.zzzzz
* <ul>
* <li>header主要声明了JWT的签名算法</li>
* <li>payload主要承载了各种声明并传递明文数据</li>
* <li>signture拥有该部分的JWT被称为JWS也就是签了名的JWS</li>
* </ul>
*
* <p>
* 详细介绍见https://www.jianshu.com/p/576dbf44b2ae
* </p>
*
* @author looly
*/
public class JWT {
private final JWTHeader header;
private final JWTPayload payload;
private Charset charset;
private JWTSigner signer;
/**
* 构造
*/
public JWT() {
this.header = new JWTHeader();
this.payload = new JWTPayload();
this.charset = CharsetUtil.CHARSET_UTF_8;
}
/**
* 设置编码
*
* @param charset 编码
* @return this
*/
public JWT setCharset(Charset charset) {
this.charset = charset;
return this;
}
/**
* 设置签名算法
*
* @param signer 签名算法
* @return this
*/
public JWT setSigner(JWTSigner signer) {
this.signer = signer;
return this;
}
/**
* 签名生成JWT字符串
*
* @return JWT字符串
*/
public String sign() {
final String headerBase64 = Base64.encodeUrlSafe(this.header.getClaimsJson(), charset);
final String payloadBase64 = Base64.encodeUrlSafe(this.payload.getClaimsJson(), charset);
final String sign = signer.sign(headerBase64, payloadBase64);
return StrUtil.format("{}.{}.{}", headerBase64, payloadBase64, sign);
}
}

View File

@@ -0,0 +1,59 @@
package cn.hutool.jwt;
import java.util.Map;
/**
* JWT头部信息
*
* @author looly
*/
public class JWTHeader extends Claims {
private static final long serialVersionUID = 1L;
//Header names
/**
* 加密算法通常为HMAC SHA256HS256
*/
public static String ALGORITHM = "alg";
/**
* 声明类型一般为jwt
*/
public static String TYPE = "typ";
/**
* 内容类型content type
*/
public static String CONTENT_TYPE = "cty";
/**
* jwk的ID编号
*/
public static String KEY_ID = "kid";
/**
* 增加“kid”头信息
*
* @param keyId kid
* @return this
*/
public JWTHeader setKeyId(String keyId) {
setClaim(KEY_ID, keyId);
return this;
}
/**
* 增加自定义JWT认证头
*
* @param headerClaims 头信息
* @return this
*/
public JWTHeader addHeaders(Map<String, ?> headerClaims) {
if (headerClaims == null) {
return this;
}
for (Map.Entry<String, ?> entry : headerClaims.entrySet()) {
setClaim(entry.getKey(), entry.getValue());
}
return this;
}
}

View File

@@ -0,0 +1,148 @@
package cn.hutool.jwt;
import java.util.Date;
import java.util.Map;
/**
* JWT载荷信息<br>
* 载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:
*
* <ul>
* <li>标准中注册的声明</li>
* <li>公共的声明</li>
* <li>私有的声明</li>
* </ul>
* <p>
* 详细介绍见https://www.jianshu.com/p/576dbf44b2ae
*
* @author looly
*/
public class JWTPayload extends Claims {
private static final long serialVersionUID = 1L;
/**
* jwt签发者
*/
public static String ISSUER = "iss";
/**
* jwt所面向的用户
*/
public static String SUBJECT = "sub";
/**
* 接收jwt的一方
*/
public static String AUDIENCE = "aud";
/**
* jwt的过期时间这个过期时间必须要大于签发时间
*/
public static String EXPIRES_AT = "exp";
/**
* 定义在什么时间之前该jwt都是不可用的.
*/
public static String NOT_BEFORE = "nbf";
/**
* jwt的签发时间
*/
public static String ISSUED_AT = "iat";
/**
* jwt的唯一身份标识主要用来作为一次性token,从而回避重放攻击。
*/
public static String JWT_ID = "jti";
/**
* 设置 jwt签发者("iss")的Payload值
*
* @param issuer jwt签发者
* @return this
*/
public JWTPayload setIssuer(String issuer) {
setClaim(ISSUER, issuer);
return this;
}
/**
* 设置jwt所面向的用户("sub")的Payload值
*
* @param subject jwt所面向的用户
* @return this
*/
public JWTPayload setSubject(String subject) {
setClaim(SUBJECT, subject);
return this;
}
/**
* 设置接收jwt的一方("aud")的Payload值
*
* @param audience 接收jwt的一方
* @return this
*/
public JWTPayload setAudience(String... audience) {
setClaim(AUDIENCE, audience);
return this;
}
/**
* Add a specific Expires At ("exp") claim to the Payload.
* 设置jwt的过期时间("exp")的Payload值这个过期时间必须要大于签发时间
*
* @param expiresAt jwt的过期时间
* @return this
* @see #setIssuedAt(Date)
*/
public JWTPayload setExpiresAt(Date expiresAt) {
setClaim(EXPIRES_AT, expiresAt);
return this;
}
/**
* 设置不可用时间点界限("nbf")的Payload值
*
* @param notBefore 不可用时间点界限在这个时间点之前jwt不可用
* @return this
*/
public JWTPayload setNotBefore(Date notBefore) {
setClaim(NOT_BEFORE, notBefore);
return this;
}
/**
* 设置jwt的签发时间("iat")
*
* @param issuedAt 签发时间
* @return this
*/
public JWTPayload setIssuedAt(Date issuedAt) {
setClaim(ISSUED_AT, issuedAt);
return this;
}
/**
* 设置jwt的唯一身份标识("jti")
*
* @param jwtId 唯一身份标识
* @return this
*/
public JWTPayload setJWTId(String jwtId) {
setClaim(JWT_ID, jwtId);
return this;
}
/**
* 增加自定义JWT认证载荷信息
*
* @param payloadClaims 载荷信息
* @return this
*/
public JWTPayload addPayload(Map<String, ?> payloadClaims) {
if (payloadClaims == null) {
return this;
}
for (Map.Entry<String, ?> entry : payloadClaims.entrySet()) {
setClaim(entry.getKey(), entry.getValue());
}
return this;
}
}

View File

@@ -0,0 +1,4 @@
/**
* JSON Web Token (JWT)封装
*/
package cn.hutool.jwt;

View File

@@ -0,0 +1,17 @@
package cn.hutool.jwt.signers;
/**
* JWT签名接口封装通过实现此接口完成不同算法的签名功能
*
* @author looly
*/
public interface JWTSigner {
/**
* 签名
* @param header JWT头的JSON字符串
* @param payload JWT载荷的JSON字符串
* @return 签名结果即JWT的第三部分
*/
String sign(String header, String payload);
}

View File

@@ -0,0 +1,4 @@
/**
* JWT签名封装
*/
package cn.hutool.jwt.signers;