All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.jwt.JWT Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.jwt;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.signers.AlgorithmUtil;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import cn.hutool.jwt.signers.NoneJWTSigner;

import java.nio.charset.Charset;
import java.security.Key;
import java.security.KeyPair;
import java.util.List;
import java.util.Map;

/**
 * JSON Web Token (JWT),基于JSON的开放标准((RFC 7519)用于在网络应用环境间传递声明。
*

* 结构:header.payload.signature *

    *
  • header:主要声明了JWT的签名算法
  • *
  • payload:主要承载了各种声明并传递明文数据
  • *
  • signature:拥有该部分的JWT被称为JWS,也就是签了名的JWS
  • *
* *

* 详细介绍见;https://www.jianshu.com/p/576dbf44b2ae *

* * @author looly * @since 5.7.0 */ public class JWT implements RegisteredPayload { private final JWTHeader header; private final JWTPayload payload; private Charset charset; private JWTSigner signer; private List tokens; /** * 创建空的JWT对象 * * @return JWT */ public static JWT create() { return new JWT(); } /** * 创建并解析JWT对象 * * @param token JWT Token字符串,格式为xxxx.yyyy.zzzz * @return JWT */ public static JWT of(String token) { return new JWT(token); } /** * 构造 */ public JWT() { this.header = new JWTHeader(); this.payload = new JWTPayload(); this.charset = CharsetUtil.CHARSET_UTF_8; } /** * 构造 * * @param token JWT Token字符串,格式为xxxx.yyyy.zzzz */ public JWT(String token) { this(); parse(token); } /** * 解析JWT内容 * * @param token JWT Token字符串,格式为xxxx.yyyy.zzzz * @return this */ public JWT parse(String token) { Assert.notBlank(token, "Token String must be not blank!"); final List tokens = splitToken(token); this.tokens = tokens; this.header.parse(tokens.get(0), this.charset); this.payload.parse(tokens.get(1), this.charset); return this; } /** * 设置编码 * * @param charset 编码 * @return this */ public JWT setCharset(Charset charset) { this.charset = charset; return this; } /** * 设置密钥,如果头部指定了算法,直接使用,否则默认算法是:HS256(HmacSHA256) * * @param key 密钥 * @return this */ public JWT setKey(byte[] key) { // 检查头信息中是否有算法信息 final String claim = (String) this.header.getClaim(JWTHeader.ALGORITHM); if (StrUtil.isNotBlank(claim)) { return setSigner(JWTSignerUtil.createSigner(claim, key)); } return setSigner(JWTSignerUtil.hs256(key)); } /** * 设置签名算法 * * @param algorithmId 签名算法ID,如HS256 * @param key 密钥 * @return this */ public JWT setSigner(String algorithmId, byte[] key) { return setSigner(JWTSignerUtil.createSigner(algorithmId, key)); } /** * 设置签名算法 * * @param algorithmId 签名算法ID,如HS256 * @param key 密钥 * @return this * @since 5.7.2 */ public JWT setSigner(String algorithmId, Key key) { return setSigner(JWTSignerUtil.createSigner(algorithmId, key)); } /** * 设置非对称签名算法 * * @param algorithmId 签名算法ID,如HS256 * @param keyPair 密钥对 * @return this * @since 5.7.2 */ public JWT setSigner(String algorithmId, KeyPair keyPair) { return setSigner(JWTSignerUtil.createSigner(algorithmId, keyPair)); } /** * 设置签名算法 * * @param signer 签名算法 * @return this */ public JWT setSigner(JWTSigner signer) { this.signer = signer; return this; } /** * 获取JWT算法签名器 * * @return JWT算法签名器 */ public JWTSigner getSigner() { return this.signer; } /** * 获取所有头信息 * * @return 头信息 */ public JSONObject getHeaders() { return this.header.getClaimsJson(); } /** * 获取头 * * @return 头信息 * @since 5.7.2 */ public JWTHeader getHeader() { return this.header; } /** * 获取头信息 * * @param name 头信息名称 * @return 头信息 */ public Object getHeader(String name) { return this.header.getClaim(name); } /** * 获取算法ID(alg)头信息 * * @return 算法头信息 * @see JWTHeader#ALGORITHM */ public String getAlgorithm() { return (String) this.header.getClaim(JWTHeader.ALGORITHM); } /** * 设置JWT头信息 * * @param name 头名 * @param value 头 * @return this */ public JWT setHeader(String name, Object value) { this.header.setClaim(name, value); return this; } /** * 增加JWT头信息 * * @param headers 头信息 * @return this */ public JWT addHeaders(Map headers) { this.header.addHeaders(headers); return this; } /** * 获取所有载荷信息 * * @return 载荷信息 */ public JSONObject getPayloads() { return this.payload.getClaimsJson(); } /** * 获取载荷对象 * * @return 载荷信息 * @since 5.7.2 */ public JWTPayload getPayload() { return this.payload; } /** * 获取载荷信息 * * @param name 载荷信息名称 * @return 载荷信息 */ public Object getPayload(String name) { return getPayload().getClaim(name); } /** * 设置JWT载荷信息 * * @param name 载荷名 * @param value 头 * @return this */ @Override public JWT setPayload(String name, Object value) { this.payload.setClaim(name, value); return this; } /** * 增加JWT载荷信息 * * @param payloads 载荷信息 * @return this */ public JWT addPayloads(Map payloads) { this.payload.addPayloads(payloads); return this; } /** * 签名生成JWT字符串 * * @return JWT字符串 */ public String sign() { return sign(true); } /** * 签名生成JWT字符串 * * @param addTypeIfNot 如果'typ'头不存在,是否赋值默认值 * @return JWT字符串 * @since 5.8.24 */ public String sign(boolean addTypeIfNot) { return sign(this.signer, addTypeIfNot); } /** * 签名生成JWT字符串 * * @param signer JWT签名器 * @return JWT字符串 */ public String sign(JWTSigner signer) { return sign(signer, true); } /** * 签名生成JWT字符串 * * @param signer JWT签名器 * @param addTypeIfNot 如果'typ'头不存在,是否赋值默认值 * @return JWT字符串 * @since 5.8.24 */ public String sign(JWTSigner signer, boolean addTypeIfNot) { Assert.notNull(signer, () -> new JWTException("No Signer provided!")); // 检查tye信息 if (addTypeIfNot) { final String type = (String) this.header.getClaim(JWTHeader.TYPE); if (StrUtil.isBlank(type)) { this.header.setClaim(JWTHeader.TYPE, "JWT"); } } // 检查头信息中是否有算法信息 final String algorithm = (String) this.header.getClaim(JWTHeader.ALGORITHM); if (StrUtil.isBlank(algorithm)) { this.header.setClaim(JWTHeader.ALGORITHM, AlgorithmUtil.getId(signer.getAlgorithm())); } final String headerBase64 = Base64.encodeUrlSafe(this.header.toString(), charset); final String payloadBase64 = Base64.encodeUrlSafe(this.payload.toString(), charset); final String sign = signer.sign(headerBase64, payloadBase64); return StrUtil.format("{}.{}.{}", headerBase64, payloadBase64, sign); } /** * 验证JWT Token是否有效 * * @return 是否有效 */ public boolean verify() { return verify(this.signer); } /** * 验证JWT是否有效,验证包括: * *
    *
  • Token是否正确
  • *
  • {@link JWTPayload#NOT_BEFORE}:生效时间不能晚于当前时间
  • *
  • {@link JWTPayload#EXPIRES_AT}:失效时间不能早于当前时间
  • *
  • {@link JWTPayload#ISSUED_AT}: 签发时间不能晚于当前时间
  • *
* * @param leeway 容忍空间,单位:秒。当不能晚于当前时间时,向后容忍;不能早于向前容忍。 * @return 是否有效 * @see JWTValidator * @since 5.7.4 */ public boolean validate(long leeway) { if (false == verify()) { return false; } // 校验时间字段 try { JWTValidator.of(this).validateDate(DateUtil.date(), leeway); } catch (ValidateException e) { return false; } return true; } /** * 验证JWT Token是否有效 * * @param signer 签名器(签名算法) * @return 是否有效 */ public boolean verify(JWTSigner signer) { if (null == signer) { // 如果无签名器提供,默认认为是无签名JWT信息 signer = NoneJWTSigner.NONE; } final List tokens = this.tokens; if (CollUtil.isEmpty(tokens)) { throw new JWTException("No token to verify!"); } return signer.verify(tokens.get(0), tokens.get(1), tokens.get(2)); } /** * 将JWT字符串拆分为3部分,无加密算法则最后一部分是"" * * @param token JWT Token * @return 三部分内容 */ private static List splitToken(String token) { final List tokens = StrUtil.split(token, CharUtil.DOT); if (3 != tokens.size()) { throw new JWTException("The token was expected 3 parts, but got {}.", tokens.size()); } return tokens; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy