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 ...
随机推荐
- WebApis中BOM的学习
1.1. 常用的键盘事件 1.1.1 键盘事件 <script> // 常用的键盘事件 //1. keyup 按键弹起的时候触发 document.addEventListener('ke ...
- 洛谷P1080 国王游戏 python解法 - 高精 贪心 排序
洛谷的题目实在是裹脚布 还编的像童话 这题要 "使得获得奖赏最多的大臣,所获奖赏尽可能的少." 看了半天都觉得不像人话 总算理解后 简单说题目的意思就是 根据既定的运算规则 如何排 ...
- IDEA 左侧出现对勾,该如何去掉对勾呢?
如下面 解决办法如下 单击按F11 或者ctrl +鼠标左键点击那个对串就可以决你的问题 有对勾是因为你把他添加进去了书签,方便下次自己看 我们可以在这个地方看到自己的书签也就是打对勾的地方
- 只有一重循环的排序——侏儒排序(Gnome Sort)
侏儒排序:从头(i=0)开始遍历元素,如果当前元素比前一个元素大(array[i]>array[i-1]),就把它跟前一个元素互换(Swap(a[i],a[i-1]))并继续检查它(i--),否 ...
- Layui + tp3.2 配合表格搜索
html 部分 <!--搜索--><fieldset class="layui-elem-field layui-field-title" style=" ...
- vue相关知识点及面试
### vue #### vue生命周期 beforeCreated `实例初始化,数据观察和event/watch事件配置之前被调用` created `实例创建后立即调用,数据观测,数据和方法运算 ...
- 如何让SpringBoot工程在log/控制台中实时打印MyBatis执行的SQL语句
工程下载:https://files.cnblogs.com/files/xiandedanteng/gatling20200429-4.zip 其实就是一句话设置的事情,实现步骤: 在applica ...
- centOS7 安装jdk压缩包版
1.到官网下载jdk https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.将压 ...
- TaskContinuationsOptions.ExecuteSynchronously探秘
TPL - Task Parallel Library为我们提供了Task相关的api,供我们非常方便的编写并行代码,而不用自己操作底层的Thread类.使用Task的优势是显而易见的: 提供返回值 ...
- oracle之三资源管理
Oracle 资源管理 12.1 为什么要使用Oracle资源管理器 传统意义上,系统的资源分配是由OS来完成的,但是对于数据库资源,OS分配资源会带来一些问题: 以Linux为例,最为突出的一个问题 ...