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 ]的更多相关文章

  1. web开发工具类

    1.日期工具类 import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { public sta ...

  2. Web 开发工具类(5) | DateUtils

    日期工具类 import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFo ...

  3. Web 开发工具类(1): CookieUtils

    CookieUtils 整合了常用的一些对Cookie的相关操作: package com.evan.common.utils; import java.io.UnsupportedEncodingE ...

  4. Web 开发工具类(2): HttpClientUtils

    HttpClientUtils 整合了一些 web开发中常用的httpClient操作: package com.evan.common.utils; import java.io.IOExcepti ...

  5. Web 开发工具类(4): IDUtils

    package com.easybuy.utils; import java.util.Random; /** * * <p>Title: IDUtils</p> * < ...

  6. Web 开发工具类(3): JsonUtils

    JsonUtils 整合了一些对Json的相关操作: package com.evan.common.utils; import java.util.List; import com.fasterxm ...

  7. Spring web 工具类 WebApplicationContextUtils

    概述 Spring web 的工具类 WebApplicationContextUtils 位于包 org.springframework.web.context.support 是访问一个Servl ...

  8. SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(五): 数据表设计、使用 jwt、redis、sms 工具类完善注册登录逻辑

    (1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 前端篇(一):搭建基本环境:https://www.cnblogs.com/l-y-h/p ...

  9. SpringMVC 常用工具类与接口

    ClassPathResource 在类路径下读取资源 public final String getPath()public boolean exists()public InputStream g ...

随机推荐

  1. 查询Linux CPU架构

    一.背景 Ubuntu上需要安装测试个软件wkhtmltopdf,但是下载时,需要知道系统架构,故做记录 二.查看linux架构 dpkg 命令 dpkg 的命令可用于查看 Debian/ Ubunt ...

  2. [PyTorch 学习笔记] 3.1 模型创建步骤与 nn.Module

    本章代码:https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson3/module_containers.py 这篇文章来看下 ...

  3. vue的修饰符

    v-on 缩写:@ 事件修饰符 .stop - 调用 event.stopPropagation(). //阻止冒泡 .prevent - 调用 event.preventDefault(). //阻 ...

  4. .NET Core3.1 Dotnetty实战第一章

    一.概要 本系列文章主要讲述由微软Azure团队研发的.net的版本的netty,Dotnetty.所有的开发都将基于.net core 3.1版本进行开发. Dotnetty是什么,原本Netty是 ...

  5. 微信小程序入门教程

    首先请看demo 很简单的静态js就可以实现一款小程序开发. js.json.html.css四个核心文件 序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小 ...

  6. frozenset冻结集合函数

    1.描述 frozenset()返回一个冻结的集合,冻结后不能添加.删除和修改. set()无序且不重复,是可以变的,有add.remove.扩展:删除重复数据,还可以计算交集.差集.并集等 2.函数 ...

  7. Hihocoder 1116 计算

    这题最开始的时候看到线段树吧,没找到好的做法 想了下既然是乘积和 (-) (--) (---) 在脑子里就是这种线条位于各个位置,然后各种长度代表连续的乘积个数 然后把所有情况累加起来,但是并不好算 ...

  8. Python自动化测试入门科技树

    Python基础: 入门语法和数据类型: 编码环境安装基本语法 常用数据类型 常用运算符 Llist.Tuple.Dict.if&for.while Python进阶: 函数: 语法 内置函数 ...

  9. intellij idea 无法进行调试的解决方案

    inteliij idea 如果出现无法调试该怎样做?debug中各功能为灰色. 如果你用的是外来项目,可能是没有添加这个项目自带的library: 解决办法: 在file->project  ...

  10. element封装表格

    <template> <div> <el-scrollbar class="table-wrap"> <el-table v-loadin ...