一、前言

本篇文章将讲述Spring Security 简单整合JWT 处理认证授权

基本环境
  1. spring-boot 2.1.8
  2. mybatis-plus 2.2.0
  3. mysql 数据库
  4. maven项目
Spring Security入门学习可参考之前文章:
  1. SpringBoot集成Spring Security入门体验(一)

    https://blog.csdn.net/qq_38225558/article/details/101754743
  2. Spring Security 自定义登录认证(二)

    https://blog.csdn.net/qq_38225558/article/details/102542072
  3. 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();
}
} }

简单的入门使用就是这样了

三、总结

  1. 引入jwt依赖
  2. 登录系统成功后生成jwt令牌返回给前端保存到浏览器请求头
  3. 在每一次请求访问系统url时,在统一认证过滤器中获取到请求头中jwt令牌中保存的用户信息然后做认证处理,如果满足条件成功访问,如果不满足交给认证失败处理器返回指定内容给前端

本文案例demo源码

https://gitee.com/zhengqingya/java-workspace

Spring Security 整合JWT(四)的更多相关文章

  1. Spring Security整合JWT,实现单点登录,So Easy~!

    前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...

  2. spring boot:spring security整合jwt实现登录和权限验证(spring boot 2.3.3)

    一,为什么使用jwt? 1,什么是jwt? Json Web Token, 它是JSON风格的轻量级的授权和身份认证规范, 可以实现无状态.分布式的Web应用授权 2,jwt的官网: https:// ...

  3. 用Spring Security, JWT, Vue实现一个前后端分离无状态认证Demo

    简介 完整代码 https://github.com/PuZhiweizuishuai/SpringSecurity-JWT-Vue-Deom 运行展示 后端 主要展示 Spring Security ...

  4. Spring Boot Security 整合 JWT 实现 无状态的分布式API接口

    简介 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案.JSON Web Token 入门教程 - 阮一峰,这篇文章可以帮你了解JWT的概念.本文重点讲解Spring Boo ...

  5. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

  6. Spring Security 整合freemaker 实现简单登录和角色控制

    Spring Security 整合freemaker 实现简单登录和角色控制     写这篇文章是因为我做了一个电商网站项目,近期刚加上权限控制.整个过程很简单,在此给大家梳理一下,也算是自己对知识 ...

  7. Spring Boot初识(4)- Spring Boot整合JWT

    一.本文介绍 上篇文章讲到Spring Boot整合Swagger的时候其实我就在思考关于接口安全的问题了,在这篇文章了我整合了JWT用来保证接口的安全性.我会先简单介绍一下JWT然后在上篇文章的基础 ...

  8. Springboot集成Spring Security实现JWT认证

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 Spring Security作为成熟且强大的安全框架,得到许多大厂的青睐.而作为前后端分离的SSO方案,JWT ...

  9. Springboot WebFlux集成Spring Security实现JWT认证

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 在之前的文章<Springboot集成Spring Security实现JWT认证>讲解了如何在传统 ...

随机推荐

  1. 神奇的 SQL 之谓词 → 难理解的 EXISTS

    前言 开心一刻 我要飞的更高,飞的更高,啊! 谓词 SQL 中的谓词指的是:返回值是逻辑值的函数.我们知道函数的返回值有可能是数字.字符串或者日期等等,但谓词的返回值全部是逻辑值(TRUE/FALSE ...

  2. spring aop介绍和示例

    参考:<Spring in Action> 一.AOP介绍 AOP是Aspect Oriented Programming的缩写,意思是面向切面编程. 应用中有一些功能使用非常普遍,比如事 ...

  3. js控制滚动条在内容更新超出时自动滚到底部

    //滚动条在内容更新时自动滚到底部var message = document.getElementById('message');message.scrollTop = message.scroll ...

  4. ASP.NET Core 3.0 gRPC 双向流

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 认证授权 一.前言 在前一文 <ASP.NE ...

  5. 从零开始用golang创建一条简单的区块链

    区块链(Blockchain),是比特币的一个重要概念,它本质上是一个去中心化的数据库,同时作为比特币的底层技术,是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一批次比特币网络交易的信息 ...

  6. Java面向对象笔记(五分钟秒懂)

    面向对象概念 面向对象三大特征:封装,继承,多态 面向对象编程(OOP,Object Oriented Programing)是相对于面向过程编程说的,之前写的代码基本都是纯的面向过程编程的,当项目复 ...

  7. 深入Dapper.NET源码 (文长)

    目录 前言.目录.安装环境 Dynamic Query 原理 Part1 Dynamic Query 原理 Part2 Strongly Typed Mapping 原理 Part1 : ADO.NE ...

  8. 《老师说的都对》第一次作业:OUC网上课程评价系统

    项目介绍: 项目名称:OUC网上课程评价系统 项目概述:实现一个公开的网上课程评价系统.开课老师也可以在自己的课程主页填写自己的课程内容介绍,学生可以在课程页面中评价自己上过的课程.为想要选课的学生提 ...

  9. Spring Boot 整合视图层技术

    这一节我们主要学习如何整合视图层技术: Jsp Freemarker Thymeleaf 在之前的案例中,我们都是通过 @RestController 来处理请求,所以返回的内容为json对象.那么如 ...

  10. vue解决刷新时闪烁

    原文地址:原文地址 1.在vue容器的div里面加上 v-cloak <div id="app" v-cloak> 2.样式文件中加上 <style type=& ...