一、前言

本篇文章将讲述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. Java抽象类构造方法

    java中抽象类的子类的构造方法会隐含父类的无参构造方法. package com.zempty.abstractclass; public class AbstractDemo01 { public ...

  2. 二、springBoot 整合 mybatis 项目实战

    前言 上一篇文章开始了我们的springboot序篇,我们配置了mysql数据库,但是我们sql语句直接写在controller中并且使用的是jdbcTemplate.项目中肯定不会这样使用,上篇文章 ...

  3. java接收控制台输入

    java控制台输入语句: Scanner sc = new Scanner(System.in); 通过一个变量,例如 int r; r = sc.nextInt();   例子: public st ...

  4. [Leetcode] 第313题 超级丑数

    一.题目描述 编写一段程序来查找第 n 个超级丑数. 超级丑数是指其所有质因数都是长度为 k 的质数列表 primes 中的正整数. 示例: 输入: n = 12, primes = [2,7,13, ...

  5. SSM框架中测试单元的使用,spring整合Junit

    测试类中的问题和解决思路   3.1.1     问题 在测试类中,每个测试方法都有以下两行代码: ApplicationContext ac = new ClassPathXmlApplicatio ...

  6. kubernetes实战(二十六):kubeadm 安装 高可用 k8s v1.16.x dashboard 2.x

    1.基本配置 基本配置.内核升级.基本服务安装参考https://www.cnblogs.com/dukuan/p/10278637.html,或者参考<再也不踩坑的Kubernetes实战指南 ...

  7. JS思考遍历对象

    var json={ “name”:”小明”, “age”:”10”, “sex”:”男” } for(var key in json); //key只是个变量名 console.log(key); ...

  8. Hadoop源代码点滴-基础概念

    大数据特征:volume(数量).variety(多样性).velocity(产生的速度) 大数据特征:多.乱.快.杂 数据的来源:业务数据.日志.管理文档(OCR).互联网.物联网.外购

  9. mysql 查找数组格式的字符串中是否包含某个值

    --#{type}表示将判断的单个值 例如 -- arr表示数组格式的字符串,例如 ,,, FIND_IN_SET(#{type},arr) 使用的时候,举例:

  10. RabbitMQ原理介绍

    RabbitMQ历史 RabbitMQ消息系统是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.在同步消息通讯的世界里有很多公开标准(如COBAR的IIO ...