Spring Security 整合JWT(四)
一、前言
本篇文章将讲述Spring Security 简单整合JWT 处理认证授权
基本环境
- spring-boot 2.1.8
- mybatis-plus 2.2.0
- mysql 数据库
- maven项目
Spring Security入门学习可参考之前文章:
- SpringBoot集成Spring Security入门体验(一)
https://blog.csdn.net/qq_38225558/article/details/101754743 - Spring Security 自定义登录认证(二)
https://blog.csdn.net/qq_38225558/article/details/102542072 - Spring Security 动态url权限控制(三)
https://blog.csdn.net/qq_38225558/article/details/102637637
二、 Spring Security 简单整合 JWT
有关JWT不了解的可以看下官网文档:https://jwt.io/introduction/

1、引入jwt依赖
<!-- jwt依赖: https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2、在Security登录认证成功后生成jwt令牌返回给前端保存
jwt生成令牌代码如下:
// 生成jwt访问令牌
String jwtToken = Jwts.builder()
// 用户角色
.claim("ROLE_LOGIN", "ADMIN")
// 主题 - 存用户名
.setSubject("张三")
// 过期时间 - 30分钟
.setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))
// 加密算法和密钥
.signWith(SignatureAlgorithm.HS512, "helloworld")
.compact();
这里贴出小编文末案例demo源码中关于登录认证处理中的使用
@Component
public class AdminAuthenticationProvider implements AuthenticationProvider {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private UserMapper userMapper;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 获取前端表单中输入后返回的用户名、密码
String userName = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
SecurityUser userInfo = (SecurityUser) userDetailsService.loadUserByUsername(userName);
boolean isValid = PasswordUtils.isValidPassword(password, userInfo.getPassword(), userInfo.getCurrentUserInfo().getSalt());
// 验证密码
if (!isValid) {
throw new BadCredentialsException("密码错误!");
}
// 前后端分离情况下 处理逻辑...
// 更新登录令牌
// 当前用户所拥有角色代码
String roleCodes = userInfo.getRoleCodes();
// 生成jwt访问令牌
String jwt = Jwts.builder()
// 用户角色
.claim(Constants.ROLE_LOGIN, roleCodes)
// 主题 - 存用户名
.setSubject(authentication.getName())
// 过期时间 - 30分钟
.setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))
// 加密算法和密钥
.signWith(SignatureAlgorithm.HS512, Constants.SALT)
.compact();
User user = userMapper.selectById(userInfo.getCurrentUserInfo().getId());
user.setToken(jwt);
userMapper.updateById(user);
userInfo.getCurrentUserInfo().setToken(jwt);
return new UsernamePasswordAuthenticationToken(userInfo, password, userInfo.getAuthorities());
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}
前端页面保存的jwt令牌格式如下:

3、Security访问鉴权中认证用户信息
我们在访问每一个url请求的时候,在统一认证的地方获取jwt中我们需要的信息然后认证即可,【注: Claims 中存放着我们需要的信息】
例如: 我们可以将用户名、密码存放jwt中,然后在认证的时候读取到其中的用户信息,然后查询数据库认证用户,如果满足条件即成功访问,如果不满足条件即抛出异常处理
温馨小提示:如果jwt令牌过期,会抛出
ExpiredJwtException异常,我们需要拦截到,然后交给认证失败处理器中处理,然后返回给前端,这里根据个人业务实际处理即可~
// 获取jwt中的信息
Claims claims = Jwts.parser().setSigningKey("helloworld").parseClaimsJws(jwtToken.replace("Bearer", "")).getBody();
// 获取当前登录用户名
System.out.println("获取当前登录用户名: " + claims.getSubject());
小编项目中认证过滤器中的使用如下:
@Slf4j
@Component
public class MyAuthenticationFilter extends OncePerRequestFilter {
@Autowired
AdminAuthenticationEntryPoint authenticationEntryPoint;
private final UserDetailsServiceImpl userDetailsService;
protected MyAuthenticationFilter(UserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request);
MultiReadHttpServletResponse wrappedResponse = new MultiReadHttpServletResponse(response);
StopWatch stopWatch = new StopWatch();
try {
stopWatch.start();
// 前后端分离情况下,前端登录后将token储存在cookie中,每次访问接口时通过token去拿用户权限
String jwtToken = wrappedRequest.getHeader(Constants.REQUEST_HEADER);
log.debug("后台检查令牌:{}", jwtToken);
if (StringUtils.isNotBlank(jwtToken)) {
// JWT相关start ===========================================
// 获取jwt中的信息
Claims claims = Jwts.parser().setSigningKey(Constants.SALT).parseClaimsJws(jwtToken.replace("Bearer", "")).getBody();
// 获取当前登录用户名
System.out.println("获取当前登录用户名: " + claims.getSubject());
// TODO 如需使用jwt特性在此做处理~
// JWT相关end ===========================================
// 检查token
SecurityUser securityUser = userDetailsService.getUserByToken(jwtToken);
if (securityUser == null || securityUser.getCurrentUserInfo() == null) {
throw new BadCredentialsException("TOKEN已过期,请重新登录!");
}
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities());
// 全局注入角色权限信息和登录用户基本信息
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(wrappedRequest, wrappedResponse);
} catch (ExpiredJwtException e) {
// jwt令牌过期
SecurityContextHolder.clearContext();
this.authenticationEntryPoint.commence(wrappedRequest, response, null);
} catch (AuthenticationException e) {
SecurityContextHolder.clearContext();
this.authenticationEntryPoint.commence(wrappedRequest, response, e);
} finally {
stopWatch.stop();
}
}
}
简单的入门使用就是这样了
三、总结
- 引入
jwt依赖 - 登录系统成功后
生成jwt令牌返回给前端保存到浏览器请求头中 - 在每一次请求访问系统url时,在统一认证过滤器中获取到请求头中jwt令牌中保存的
用户信息然后做认证处理,如果满足条件成功访问,如果不满足交给认证失败处理器返回指定内容给前端
本文案例demo源码
https://gitee.com/zhengqingya/java-workspace
Spring Security 整合JWT(四)的更多相关文章
- Spring Security整合JWT,实现单点登录,So Easy~!
前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...
- spring boot:spring security整合jwt实现登录和权限验证(spring boot 2.3.3)
一,为什么使用jwt? 1,什么是jwt? Json Web Token, 它是JSON风格的轻量级的授权和身份认证规范, 可以实现无状态.分布式的Web应用授权 2,jwt的官网: https:// ...
- 用Spring Security, JWT, Vue实现一个前后端分离无状态认证Demo
简介 完整代码 https://github.com/PuZhiweizuishuai/SpringSecurity-JWT-Vue-Deom 运行展示 后端 主要展示 Spring Security ...
- Spring Boot Security 整合 JWT 实现 无状态的分布式API接口
简介 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案.JSON Web Token 入门教程 - 阮一峰,这篇文章可以帮你了解JWT的概念.本文重点讲解Spring Boo ...
- 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权
一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...
- Spring Security 整合freemaker 实现简单登录和角色控制
Spring Security 整合freemaker 实现简单登录和角色控制 写这篇文章是因为我做了一个电商网站项目,近期刚加上权限控制.整个过程很简单,在此给大家梳理一下,也算是自己对知识 ...
- Spring Boot初识(4)- Spring Boot整合JWT
一.本文介绍 上篇文章讲到Spring Boot整合Swagger的时候其实我就在思考关于接口安全的问题了,在这篇文章了我整合了JWT用来保证接口的安全性.我会先简单介绍一下JWT然后在上篇文章的基础 ...
- Springboot集成Spring Security实现JWT认证
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 Spring Security作为成熟且强大的安全框架,得到许多大厂的青睐.而作为前后端分离的SSO方案,JWT ...
- Springboot WebFlux集成Spring Security实现JWT认证
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 在之前的文章<Springboot集成Spring Security实现JWT认证>讲解了如何在传统 ...
随机推荐
- Linux变量替换技术
1.1.1 ${value:-word} 如果变量value没有定义,则返回word,如果已经赋值则返回value变量的值 result=${jimyy:-UNSET} echo $result ...
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题解报告
来刷kuangbin字符串了,字符串处理在ACM中是很重要的,一般比赛都会都1——2道有关字符串处理的题目,而且不会很难的那种,大多数时候都是用到一些KMP的性质或者找规律. 点击标题可跳转至VJ比赛 ...
- TestNG(九) 异常测试
package com.course.testng.suite; import org.testng.annotations.Test; public class ExpectedExeption { ...
- vscode主题安装
安装主题 快捷键Ctrl+Shift+X打开安装插件 搜索Monokai ST3 切换主题 显示效果 安装文件图标 扩展插件vscode-icon 鼠标滚轮设置字体大小 打开setting.json文 ...
- 48 (OC)* 适配iPad和iPhone、以及横竖屏适配。
一:核心方法 1.三个方法 1.1:开始就会触发 - (void)viewWillLayoutSubviews; 1.2:开始就会触发 - (void)viewDidLayoutSubviews; 1 ...
- 【PyTorch】Tricks 集锦
声明:本文大部分内容是从知乎.博客等知识分享站点摘录而来,以方便查阅学习.具体摘录地址已在文章底部引用部分给出. 1. 查看模型每层输出详情 from torchsummary import summ ...
- java架构之路-(mysql底层原理)Mysql之让我们再深撸一次mysql
让我再深撸一次mysql吧,这次主要以应对面试来说说mysql,大概几个方向,索引结构,查询引擎,索引优化,explain的详解和trace工具的使用. 索引: 我们先来看一下mysql的B+tree ...
- spring5 源码深度解析----- AOP的使用及AOP自定义标签
我们知道在面向对象OOP编程存在一些弊端,当需要为多个不具有继承关系的对象引入同一个公共行为时,例如日志,安全检测等,我们只有在每个对象里引入公共行为,这样程序中就产生了大量的重复代码,所以有了面向对 ...
- mysql 版本引起的 utf8mb4 问题(linux centos6.9下升级mysql)
文字输入时候存在火星文或者表情,insert到低版本的mysql中一般会报错,所以我们需要将mysql版本升级到5.5.3及以上,高版本的mysql为我们提供了utf8mb4的编码,解决了这些复杂数据 ...
- 阿里云服务器CentOS6.9 nexus私服配置
从nexus官网下载nexus版本. 下载地址如下:https://help.sonatype.com/repomanager2/download 如果要下载3.X版本的,可以把repomanager ...