pom.xml


  1. <dependency>
  2. <groupId>io.jsonwebtoken</groupId>
  3. <artifactId>jjwt</artifactId>
  4. <version>0.9.0</version>
  5. </dependency>

JwtUtil.java


  1. package com.app.core.util;
  2. import io.jsonwebtoken.Claims;
  3. import io.jsonwebtoken.Jws;
  4. import io.jsonwebtoken.Jwts;
  5. import io.jsonwebtoken.SignatureAlgorithm;
  6. import io.jsonwebtoken.impl.crypto.MacProvider;
  7. import lombok.extern.log4j.Log4j2;
  8. import org.apache.commons.codec.binary.Base64;
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.joda.time.DateTime;
  11. import javax.crypto.SecretKey;
  12. import javax.crypto.spec.SecretKeySpec;
  13. import java.security.Key;
  14. import java.util.Date;
  15. import java.util.UUID;
  16. /**
  17. * JWT校验工具类
  18. * <ol>
  19. * <li>iss: jwt签发者</li>
  20. * <li>sub: jwt所面向的用户</li>
  21. * <li>aud: 接收jwt的一方</li>
  22. * <li>exp: jwt的过期时间,这个过期时间必须要大于签发时间</li>
  23. * <li>nbf: 定义在什么时间之前,该jwt都是不可用的</li>
  24. * <li>iat: jwt的签发时间</li>
  25. * <li>jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击</li>
  26. * </ol>
  27. */
  28. @Log4j2
  29. public class JwtUtil {
  30. /**
  31. * JWT 加解密类型
  32. */
  33. private static final SignatureAlgorithm JWT_ALG = SignatureAlgorithm.HS256;
  34. /**
  35. * JWT 生成密钥使用的密码
  36. */
  37. private static final String JWT_RULE = "wjtree.xin";
  38. /**
  39. * JWT 添加至HTTP HEAD中的前缀
  40. */
  41. private static final String JWT_SEPARATOR = "Bearer ";
  42. /**
  43. * 使用JWT默认方式,生成加解密密钥
  44. *
  45. * @param alg 加解密类型
  46. * @return
  47. */
  48. public static SecretKey generateKey(SignatureAlgorithm alg) {
  49. return MacProvider.generateKey(alg);
  50. }
  51. /**
  52. * 使用指定密钥生成规则,生成JWT加解密密钥
  53. *
  54. * @param alg 加解密类型
  55. * @param rule 密钥生成规则
  56. * @return
  57. */
  58. public static SecretKey generateKey(SignatureAlgorithm alg, String rule) {
  59. // 将密钥生成键转换为字节数组
  60. byte[] bytes = Base64.decodeBase64(rule);
  61. // 根据指定的加密方式,生成密钥
  62. return new SecretKeySpec(bytes, alg.getJcaName());
  63. }
  64. /**
  65. * 构建JWT
  66. *
  67. * @param alg jwt 加密算法
  68. * @param key jwt 加密密钥
  69. * @param sub jwt 面向的用户
  70. * @param aud jwt 接收方
  71. * @param jti jwt 唯一身份标识
  72. * @param iss jwt 签发者
  73. * @param nbf jwt 生效日期时间
  74. * @param duration jwt 有效时间,单位:秒
  75. * @return JWT字符串
  76. */
  77. public static String buildJWT(SignatureAlgorithm alg, Key key, String sub, String aud, String jti, String iss, Date nbf, Integer duration) {
  78. // jwt的签发时间
  79. DateTime iat = DateTime.now();
  80. // jwt的过期时间,这个过期时间必须要大于签发时间
  81. DateTime exp = null;
  82. if (duration != null)
  83. exp = (nbf == null ? iat.plusSeconds(duration) : new DateTime(nbf).plusSeconds(duration));
  84. // 获取JWT字符串
  85. String compact = Jwts.builder()
  86. .signWith(alg, key)
  87. .setSubject(sub)
  88. .setAudience(aud)
  89. .setId(jti)
  90. .setIssuer(iss)
  91. .setNotBefore(nbf)
  92. .setIssuedAt(iat.toDate())
  93. .setExpiration(exp != null ? exp.toDate() : null)
  94. .compact();
  95. // 在JWT字符串前添加"Bearer "字符串,用于加入"Authorization"请求头
  96. return JWT_SEPARATOR + compact;
  97. }
  98. /**
  99. * 构建JWT
  100. *
  101. * @param sub jwt 面向的用户
  102. * @param aud jwt 接收方
  103. * @param jti jwt 唯一身份标识
  104. * @param iss jwt 签发者
  105. * @param nbf jwt 生效日期时间
  106. * @param duration jwt 有效时间,单位:秒
  107. * @return JWT字符串
  108. */
  109. public static String buildJWT(String sub, String aud, String jti, String iss, Date nbf, Integer duration) {
  110. return buildJWT(JWT_ALG, generateKey(JWT_ALG, JWT_RULE), sub, aud, jti, iss, nbf, duration);
  111. }
  112. /**
  113. * 构建JWT
  114. *
  115. * @param sub jwt 面向的用户
  116. * @param jti jwt 唯一身份标识,主要用来作为一次性token,从而回避重放攻击
  117. * @return JWT字符串
  118. */
  119. public static String buildJWT(String sub, String jti, Integer duration) {
  120. return buildJWT(sub, null, jti, null, null, duration);
  121. }
  122. /**
  123. * 构建JWT
  124. * <p>使用 UUID 作为 jti 唯一身份标识</p>
  125. * <p>JWT有效时间 600 秒,即 10 分钟</p>
  126. *
  127. * @param sub jwt 面向的用户
  128. * @return JWT字符串
  129. */
  130. public static String buildJWT(String sub) {
  131. return buildJWT(sub, null, UUID.randomUUID().toString(), null, null, 600);
  132. }
  133. /**
  134. * 解析JWT
  135. *
  136. * @param key jwt 加密密钥
  137. * @param claimsJws jwt 内容文本
  138. * @return {@link Jws}
  139. * @throws Exception
  140. */
  141. public static Jws<Claims> parseJWT(Key key, String claimsJws) {
  142. // 移除 JWT 前的"Bearer "字符串
  143. claimsJws = StringUtils.substringAfter(claimsJws, JWT_SEPARATOR);
  144. // 解析 JWT 字符串
  145. return Jwts.parser().setSigningKey(key).parseClaimsJws(claimsJws);
  146. }
  147. /**
  148. * 校验JWT
  149. *
  150. * @param claimsJws jwt 内容文本
  151. * @return ture or false
  152. */
  153. public static Boolean checkJWT(String claimsJws) {
  154. boolean flag = false;
  155. try {
  156. SecretKey key = generateKey(JWT_ALG, JWT_RULE);
  157. // 获取 JWT 的 payload 部分
  158. flag = (parseJWT(key, claimsJws).getBody() != null);
  159. } catch (Exception e) {
  160. log.warn("JWT验证出错,错误原因:{}", e.getMessage());
  161. }
  162. return flag;
  163. }
  164. /**
  165. * 校验JWT
  166. *
  167. * @param key jwt 加密密钥
  168. * @param claimsJws jwt 内容文本
  169. * @param sub jwt 面向的用户
  170. * @return ture or false
  171. */
  172. public static Boolean checkJWT(Key key, String claimsJws, String sub) {
  173. boolean flag = false;
  174. try {
  175. // 获取 JWT 的 payload 部分
  176. Claims claims = parseJWT(key, claimsJws).getBody();
  177. // 比对JWT中的 sub 字段
  178. flag = claims.getSubject().equals(sub);
  179. } catch (Exception e) {
  180. log.warn("JWT验证出错,错误原因:{}", e.getMessage());
  181. }
  182. return flag;
  183. }
  184. /**
  185. * 校验JWT
  186. *
  187. * @param claimsJws jwt 内容文本
  188. * @param sub jwt 面向的用户
  189. * @return ture or false
  190. */
  191. public static Boolean checkJWT(String claimsJws, String sub) {
  192. return checkJWT(generateKey(JWT_ALG, JWT_RULE), claimsJws, sub);
  193. }
  194. }

AuthorizationInterceptor.java


  1. package com.app.web.core;
  2. import com.app.core.util.JwtUtil;
  3. import lombok.extern.log4j.Log4j2;
  4. import org.apache.commons.lang3.StringUtils;
  5. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. /**
  9. * 请求鉴权拦截器
  10. */
  11. @Log4j2
  12. public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
  13. @Override
  14. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  15. boolean flag = false;
  16. // 获取 HTTP HEAD 中的 TOKEN
  17. String authorization = request.getHeader("Authorization");
  18. // 校验 TOKEN
  19. flag = StringUtils.isNotBlank(authorization) ? JwtUtil.checkJWT(authorization) : false;
  20. // 如果校验未通过,返回 401 状态
  21. if (!flag)
  22. response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  23. return flag;
  24. }
  25. }

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. 《Java从入门到失业》第三章:基础语法及基本程序结构(四):基本数据类型(字符编码和char型)

    3.6.4字符编码 咦?怎么好像有东西乱入了?不是讲基本数据类型么?哈哈,因为还剩下最后一个char型了,因为char型会牵涉到Unicode编码相关,因此我决定先科普一下字符集编码. 我儿子现在上小 ...

  2. asp.net报表结构学习记录

    当一份web报表项目压缩包躺在我的文件夹里时,我是完全懵的.作为一个学习了一个月java的asp.net小白,以前从来没有接触过这方面,我完全不知道从何入手. 手里也有asp.net开发学习视频,但都 ...

  3. java父类子类代码

    import java.util.Scanner;import java.util.*; class PersonF{ public void print(String ID,String Workc ...

  4. 远程调试在Linux车机中的应用

    导读 在软件开发过程中,调试是必不可少的环节,嵌入式操作系统的调试与桌面操作系统的调试相比有很大差别,嵌入式系统的可视化调试能力比桌面操作系统要弱一点.对于导航这种业务场景比较复杂的程序开发,可视化调 ...

  5. 4300 字Python列表使用总结,用心!

    今天列表专题的目录如下: 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这 ...

  6. 记录使用vs code两天的心得

    一个字 就是骚~感觉以后写博客都省了

  7. Funny Positive Sequence (思维+前缀)

    There are n integers a 1,a 2,…,a n-1,a n in the sequence A, the sum of these n integers is larger th ...

  8. 手机预览本地html

    下载nginx,地址http://nginx.org/en/docs/windows.html 解压后替换html中内容即可 在浏览器输入http://localhost/即可预览    或者换成ip ...

  9. Spring框架学习笔记(1)

    Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...

  10. 2020云栖大会智慧出行专场:聚焦高精地图/算法、智能模型、自动驾驶、AR导航

    2020云栖大会将于9月17日-18日在线举行,届时将通过官网为全球科技人带来前沿科技.技术产品.产业应用等领域的系列重要分享.   阿里巴巴高德地图携手合作伙伴精心筹备了“智慧出行”专场.我们将为大 ...