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认证>讲解了如何在传统 ...
随机推荐
- 前端黑魔法:webworker动态化,无需JS文件创建worker
前言 前几天,我和一位知乎网友讨论这个问题的时候,觉得这非常有意思,所以写了这篇文章作为记录 本文的思路和项目代码来源于知友 @simon3000,我加以修饰以更符合理解的需求. 本文所用代码已经 ...
- C++11新增容器以及元组
上次说了C++11的部分新特性,这里我们来说说新增的容器. unordered_map unordered_set unordered_multimap unordered_multiset arra ...
- CentOS在VMware中的安装
1.启动VMware 2.新建一台虚拟机,选择典型 3.选择稍后安装操作系统 4.选择引导系统为Linux,系统版本为Centos 5.选择安装位置 6.选择最大磁盘容量 7.点击自定义硬件,进行硬件 ...
- Vue学习之vue中的v-if,v-show,v-for
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [AWS] S3 Bucket
云存储服务 2.1 为网站打开属性 属性和权限设置 设置bucket属性,打开功能:Static website hosting(静态网站托管) 设置bucket权限,Permissions ---- ...
- React + TypeScript 实现泛型组件
泛型类型 TypeScript 中,类型(interface, type)是可以声明成泛型的,这很常见. interface Props<T> { content: T; } 这表明 Pr ...
- 在Docker中启动Cloudera
写在前面 记录一下,一个简单的cloudera处理平台的构建过程和一些基本组件的使用 前置说明 需要一台安装有Docker的机器 docker常用命令: docker ps docker ps -a ...
- 重学JavaScript之面向对象的程序设计(继承)
1. 继承 ES 中只支持实现继承,而且其实现继承主要依靠原型链来实现的. 2. 原型链 ES中 描述了 原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引 ...
- Java基础学习笔记(一) - 基础语法
1.Java程序开发过程 编译: 是指将我们编写的Java源文件翻译成JVM认识的class文件,javac编译器会检查我们所写的程序是否有错误,有错误就会提示出来,如果没有错误就会编译成功. 运行: ...
- 记一次linux Docker网络故障排除经历
背景: 之前做了一个项目,需要在容器内访问宿主机提供的Redis 服务(这是一个比较常见的应用场景哈), 常规方案: ① 主机网络(docker run --network=host): 完全应用 ...