SON Web Tokens 工具类 [ JwtUtil ]
pom.xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
JwtUtil.java
package com.app.core.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.MacProvider;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;
import java.util.UUID;
/**
* JWT校验工具类
* <ol>
* <li>iss: jwt签发者</li>
* <li>sub: jwt所面向的用户</li>
* <li>aud: 接收jwt的一方</li>
* <li>exp: jwt的过期时间,这个过期时间必须要大于签发时间</li>
* <li>nbf: 定义在什么时间之前,该jwt都是不可用的</li>
* <li>iat: jwt的签发时间</li>
* <li>jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击</li>
* </ol>
*/
@Log4j2
public class JwtUtil {
/**
* JWT 加解密类型
*/
private static final SignatureAlgorithm JWT_ALG = SignatureAlgorithm.HS256;
/**
* JWT 生成密钥使用的密码
*/
private static final String JWT_RULE = "wjtree.xin";
/**
* JWT 添加至HTTP HEAD中的前缀
*/
private static final String JWT_SEPARATOR = "Bearer ";
/**
* 使用JWT默认方式,生成加解密密钥
*
* @param alg 加解密类型
* @return
*/
public static SecretKey generateKey(SignatureAlgorithm alg) {
return MacProvider.generateKey(alg);
}
/**
* 使用指定密钥生成规则,生成JWT加解密密钥
*
* @param alg 加解密类型
* @param rule 密钥生成规则
* @return
*/
public static SecretKey generateKey(SignatureAlgorithm alg, String rule) {
// 将密钥生成键转换为字节数组
byte[] bytes = Base64.decodeBase64(rule);
// 根据指定的加密方式,生成密钥
return new SecretKeySpec(bytes, alg.getJcaName());
}
/**
* 构建JWT
*
* @param alg jwt 加密算法
* @param key jwt 加密密钥
* @param sub jwt 面向的用户
* @param aud jwt 接收方
* @param jti jwt 唯一身份标识
* @param iss jwt 签发者
* @param nbf jwt 生效日期时间
* @param duration jwt 有效时间,单位:秒
* @return JWT字符串
*/
public static String buildJWT(SignatureAlgorithm alg, Key key, String sub, String aud, String jti, String iss, Date nbf, Integer duration) {
// jwt的签发时间
DateTime iat = DateTime.now();
// jwt的过期时间,这个过期时间必须要大于签发时间
DateTime exp = null;
if (duration != null)
exp = (nbf == null ? iat.plusSeconds(duration) : new DateTime(nbf).plusSeconds(duration));
// 获取JWT字符串
String compact = Jwts.builder()
.signWith(alg, key)
.setSubject(sub)
.setAudience(aud)
.setId(jti)
.setIssuer(iss)
.setNotBefore(nbf)
.setIssuedAt(iat.toDate())
.setExpiration(exp != null ? exp.toDate() : null)
.compact();
// 在JWT字符串前添加"Bearer "字符串,用于加入"Authorization"请求头
return JWT_SEPARATOR + compact;
}
/**
* 构建JWT
*
* @param sub jwt 面向的用户
* @param aud jwt 接收方
* @param jti jwt 唯一身份标识
* @param iss jwt 签发者
* @param nbf jwt 生效日期时间
* @param duration jwt 有效时间,单位:秒
* @return JWT字符串
*/
public static String buildJWT(String sub, String aud, String jti, String iss, Date nbf, Integer duration) {
return buildJWT(JWT_ALG, generateKey(JWT_ALG, JWT_RULE), sub, aud, jti, iss, nbf, duration);
}
/**
* 构建JWT
*
* @param sub jwt 面向的用户
* @param jti jwt 唯一身份标识,主要用来作为一次性token,从而回避重放攻击
* @return JWT字符串
*/
public static String buildJWT(String sub, String jti, Integer duration) {
return buildJWT(sub, null, jti, null, null, duration);
}
/**
* 构建JWT
* <p>使用 UUID 作为 jti 唯一身份标识</p>
* <p>JWT有效时间 600 秒,即 10 分钟</p>
*
* @param sub jwt 面向的用户
* @return JWT字符串
*/
public static String buildJWT(String sub) {
return buildJWT(sub, null, UUID.randomUUID().toString(), null, null, 600);
}
/**
* 解析JWT
*
* @param key jwt 加密密钥
* @param claimsJws jwt 内容文本
* @return {@link Jws}
* @throws Exception
*/
public static Jws<Claims> parseJWT(Key key, String claimsJws) {
// 移除 JWT 前的"Bearer "字符串
claimsJws = StringUtils.substringAfter(claimsJws, JWT_SEPARATOR);
// 解析 JWT 字符串
return Jwts.parser().setSigningKey(key).parseClaimsJws(claimsJws);
}
/**
* 校验JWT
*
* @param claimsJws jwt 内容文本
* @return ture or false
*/
public static Boolean checkJWT(String claimsJws) {
boolean flag = false;
try {
SecretKey key = generateKey(JWT_ALG, JWT_RULE);
// 获取 JWT 的 payload 部分
flag = (parseJWT(key, claimsJws).getBody() != null);
} catch (Exception e) {
log.warn("JWT验证出错,错误原因:{}", e.getMessage());
}
return flag;
}
/**
* 校验JWT
*
* @param key jwt 加密密钥
* @param claimsJws jwt 内容文本
* @param sub jwt 面向的用户
* @return ture or false
*/
public static Boolean checkJWT(Key key, String claimsJws, String sub) {
boolean flag = false;
try {
// 获取 JWT 的 payload 部分
Claims claims = parseJWT(key, claimsJws).getBody();
// 比对JWT中的 sub 字段
flag = claims.getSubject().equals(sub);
} catch (Exception e) {
log.warn("JWT验证出错,错误原因:{}", e.getMessage());
}
return flag;
}
/**
* 校验JWT
*
* @param claimsJws jwt 内容文本
* @param sub jwt 面向的用户
* @return ture or false
*/
public static Boolean checkJWT(String claimsJws, String sub) {
return checkJWT(generateKey(JWT_ALG, JWT_RULE), claimsJws, sub);
}
}
AuthorizationInterceptor.java
package com.app.web.core;
import com.app.core.util.JwtUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 请求鉴权拦截器
*/
@Log4j2
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
boolean flag = false;
// 获取 HTTP HEAD 中的 TOKEN
String authorization = request.getHeader("Authorization");
// 校验 TOKEN
flag = StringUtils.isNotBlank(authorization) ? JwtUtil.checkJWT(authorization) : false;
// 如果校验未通过,返回 401 状态
if (!flag)
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return flag;
}
}
SON Web Tokens 工具类 [ JwtUtil ]的更多相关文章
- web开发工具类
1.日期工具类 import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { public sta ...
- Web 开发工具类(5) | DateUtils
日期工具类 import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFo ...
- Web 开发工具类(1): CookieUtils
CookieUtils 整合了常用的一些对Cookie的相关操作: package com.evan.common.utils; import java.io.UnsupportedEncodingE ...
- Web 开发工具类(2): HttpClientUtils
HttpClientUtils 整合了一些 web开发中常用的httpClient操作: package com.evan.common.utils; import java.io.IOExcepti ...
- Web 开发工具类(4): IDUtils
package com.easybuy.utils; import java.util.Random; /** * * <p>Title: IDUtils</p> * < ...
- Web 开发工具类(3): JsonUtils
JsonUtils 整合了一些对Json的相关操作: package com.evan.common.utils; import java.util.List; import com.fasterxm ...
- Spring web 工具类 WebApplicationContextUtils
概述 Spring web 的工具类 WebApplicationContextUtils 位于包 org.springframework.web.context.support 是访问一个Servl ...
- SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(五): 数据表设计、使用 jwt、redis、sms 工具类完善注册登录逻辑
(1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(一):搭建基本环境:https://www.cnblogs.com/l-y-h/p ...
- SpringMVC 常用工具类与接口
ClassPathResource 在类路径下读取资源 public final String getPath()public boolean exists()public InputStream g ...
随机推荐
- 洛谷 P3951 NOIP 2017 小凯的疑惑
洛谷 P3951 NOIP 2017 小凯的疑惑 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付 ...
- OGG复制同步,提示字段长度不够ORA-01704
日常运维OGG的环境中,如果遇到复制进程报错,提示字段长度不足如何处理??? 正常情况下,字段长度不足,但是未达到Oracle的限制时,可以对字段进行扩大限制满足目的. 实际环境中,遇到源端GBK,目 ...
- mysql再回首
Mysql与Oracle的区别 1.实例区别 Mysql是一个轻量型数据库,开源免费.Oracle是收费的而且价格非常高. Mysql一个实例可以操作多个库,而Oracle一个实例只能对应一个库. M ...
- idea,git操作
原文地址:https://blog.csdn.net/lzx2018/article/details/91414591 1新建分支 点击New Branch 2切换分支
- 新手学习seo写原创文章的方法
http://www.wocaoseo.com/thread-102-1-1.html 前两天都是写自己公司克拉玛依电信公司年终活动和总结的事,今天继续学习seo技术,其实说难也难说容易也容易,关键的 ...
- py_二分查找
''' 查找:在一些数据元素中,通过一定的方法找出与关键字相同元素的过程, 列表查找:从列表中查找指定元素 输入:列表.待查找元素 输出:元素下标(未找到元素时一般返回None或-1) 内置列表查找函 ...
- Mac 系统安装robot framework
1.安装Python3 版本 2.安装robotframework:pip3 install robotframework 3.安装Pypubsub:pip3 install Pypubsub 4.安 ...
- pymssql 介绍
pymssql包是Python语言用于连接SQL Server数据库的驱动程序(或者称作DB API),它是最终和数据库进行交互的工具.SQLAlchemy包就是利用pymssql包实现和SQL Se ...
- unity3d插入android有米广告
有米官网:http://www.youmi.net/register?r=MTI0MDg= 国内的广告,我觉得万普和有米还不错,我也只试了这两个,其他的都是看评价的,呵呵~~~首先我们去有米官网注册一 ...
- Mysql表,列,库的增删查改
下面是我总结的一些基础的sql知识,主要是为了以后更好的查阅和帮助其他初学的人,同时记录自己的成长,还写了一点稍有难度的sql面试题级别的题目,好了废话不多说,见真题... #创建数据库 CREATE ...