当前位置: 首页 > news >正文

Springboot集成token认证

一、引出session问题以及token、鉴权

  1. session都是保存在内存中,认证用户增多,服务端开销明显增大。
  2. 若是认证的记录保存在某台服务器内存中时,意味着用户的下次请求只能够在该服务器内存中进行认证。
  3. CSRF跨站攻击

token的鉴权机制:http协议也是无状态的,不需要在服务端去保留用户的认证信息或者会话信息。这也就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录

鉴权流程:简单来说就是服务器根据前端传来的用户名与密码生成token并返回前端,前端之后的请求都会携带该cookie来进行执行操作认证。

  1. 用户使用用户名密码来请求服务器。
  2. 服务器进行验证用户的信息。
  3. 服务器通过验证生成token发送给用户一个token。
  4. 客户端存储token,并在每次请求时附送上这个token值。
  5. 服务端验证token值,并返回数据。

这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS

二、认识JWT(三部分详细构成)

JWT(JSON WEB TOKEN)是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串.

  • 第一部分:头部(header)。
  • 第二部分:载荷(payload),携带的信息。
  • 第三部分:签证(signature)。

三、Spring Security 

Spring Security

是一个强大且高度可定制的身份验证和访问控制框架。它是保护基于Spring的应用程序的实际标准。Spring Security是一个可以为Java应用程序提供全面安全服务的框架。同时,它也可以轻松扩展以满足自定义需求。 

主要功能
Authentication (认证),就是用户登录
Authorization (授权):一旦身份验证成功,判断用户拥有什么权限,可以访问什么资源
防止跨站请求伪造(CSRF):Spring Security提供了内置的防护机制,可以防止跨站请求伪造攻击。
密码存储:Spring Security提供了多种密码存储格式,包括明文、加密和哈希。
集成其他安全框架:Spring Security可以与其他安全框架如OAuth2、JWT等进行集成,以提供更全面的安全解决方案。

SpringSecurity 采用的是责任链的设计模式,它有一条很长的过滤器链。

SecurityContextPersistenceFilter:每次请求处理之前将该请求相关的安全上下文信息加载到 SecurityContextHolder 中。
LogoutFilter:用于处理退出登录。
UsernamePasswordAuthenticationFilter:用于处理基于表单的登录请求,从表单中获取用户名和密码。
BasicAuthenticationFilter:检测和处理 http basic 认证。
ExceptionTranslationFilter:处理过滤器链中抛出的任何AccessDeniedException和AuthenticationException 。
FilterSecurityInterceptor:负责权限校验的过滤器,可以看做过滤器链的出口。

2. JWT校验登录的校验流程

首先前端一样是把登录信息发送给后端,后端查询数据库校验用户的账号和密码是否正确,正确的话则使用jwt生成token,并且返回给前端。以后前端每次请求时,都需要携带token,后端获取token后,使用jwt进行验证用户的token是否无效或过期,验证成功后才去做相应的逻辑。

四、Spring Boot整合Redis、SpringSecurity、JWT

 

  1. 添加依赖项在 pom.xml 文件中添加以下依赖项:
   <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
</dependencies>

 创建Redis配置类

@Configuration
public class RedisConfig {@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port}")private int port;@Beanpublic JedisConnectionFactory jedisConnectionFactory() {return new JedisConnectionFactory(new RedisStandaloneConfiguration(host, port));}@Beanpublic RedisTemplate<String, Object> redisTemplate() {final RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(jedisConnectionFactory());return template;}
}

 创建 JwtTokenUtil 类,用于生成和验证JWT令牌。

@Component
public class JwtTokenUtil implements Serializable {private static final long serialVersionUID = -2550185165626007488L;private static final String secret = "mySecret";public String getUsernameFromToken(String token) {return getClaimFromToken(token, Claims::getSubject);}public Date getExpirationDateFromToken(String token) {return getClaimFromToken(token, Claims::getExpiration);}public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {final Claims claims = getAllClaimsFromToken(token);return claimsResolver.apply(claims);}private Claims getAllClaimsFromToken(String token) {return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}private Boolean isTokenExpired(String token) {final Date expiration = getExpirationDateFromToken(token);return expiration.before(new Date());}public String generateToken(UserDetails userDetails) {Map<String, Object> claims = new HashMap<>();return doGenerateToken(claims, userDetails.getUsername());}private String doGenerateToken(Map<String, Object> claims, String subject) {return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis())).setExpiration(new Date(System.currentTimeMillis() + 5 * 60 * 60 * 1000)).signWith(SignatureAlgorithm.HS512, secret).compact();}public Boolean validateToken(String token, UserDetails userDetails) {final String username = getUsernameFromToken(token);return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));}
}

 创建 JwtAuthenticationEntryPoint 类,用于处理未经授权的请求。

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {private static final long serialVersionUID = -7858869558953243875L;@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response,AuthenticationException authException) throws IOException {response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");}
}

 创建 JwtRequestFilter 类,用于解析和验证JWT令牌。

@Component
public class JwtRequestFilter extends OncePerRequestFilter {@Autowiredprivate MyUserDetailsService myUserDetailsService;@Autowiredprivate JwtTokenUtil jwtTokenUtil;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {final String requestTokenHeader = request.getHeader("Authorization");String username = null;String jwtToken = null;if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {jwtToken = requestTokenHeader.substring(7);try {username = jwtTokenUtil.getUsernameFromToken(jwtToken);} catch (IllegalArgumentException e) {System.out.println("Unable to get JWT Token");} catch (ExpiredJwtException e) {System.out.println("JWT Token has expired");}} else {logger.warn("JWT Token does not begin with Bearer String");}if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {UserDetails userDetails = this.myUserDetailsService.loadUserByUsername(username);if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);}}chain.doFilter(request, response);}
}

 配置Spring Security

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;@Autowiredprivate UserDetailsService jwtUserDetailsService;@Autowiredprivate JwtRequestFilter jwtRequestFilter;@Autowiredpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity.csrf().disable().authorizeRequests().antMatchers("/authenticate").permitAll().anyRequest().authenticated().and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);}
}

相关文章:

Springboot集成token认证

一、引出session问题以及token、鉴权 session都是保存在内存中&#xff0c;认证用户增多&#xff0c;服务端开销明显增大。若是认证的记录保存在某台服务器内存中时&#xff0c;意味着用户的下次请求只能够在该服务器内存中进行认证。CSRF跨站攻击 token的鉴权机制&#xff1…...

计算机网络_工具

从你的电脑到指定ip网站&#xff0c;用时3ms ttl TTL Time To Live 数据包存活时间 指一个数据包在经过一个路由器时&#xff0c;可传递的最长距离&#xff08;跃点数&#xff09;。每当数据包经过一个路由器时&#xff0c;其存活次数就会被减一 256 - 249 7&…...

如何实现一个Java的@注解?

先看一段代码&#xff1a; ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(value Exception.class)public ResponseEntity defaultErrorHandler(Exception e) {// 将错误信息转成字符串String errorMessage ExceptionUtils.getStackTrace(e);// 创…...

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记12:DAC数模转换

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…...

迅饶科技 X2Modbus 网关 GetUser 信息泄露漏洞复现

0x01 产品简介 X2Modbus是上海迅饶自动化科技有限公司Q开发的一款功能很强大的协议转换网关, 这里的X代表各家不同的通信协议, 2是T0的谐音表示转换, Modbus就是最终支持的标准协议是Modbus协议。用户可以根据现场设备的通信协议进行配置,转成标准的Modbus协议。在PC端仿真…...

修改亚马逊云科技账户的密码和MFA

要使用AWS CLI删除当前账户的多因素认证(MFA)设备并修改密码&#xff0c;你需要先确保已安装并配置了AWS CLI&#xff0c;并且你的账户有足够的权限执行这些操作。下面是如何分步进行的指导&#xff1a; 1. 删除MFA设备 首先&#xff0c;你需要找出MFA设备的序列号或ARN。可以…...

提升性能与精准追踪:SkyWalking自定义跟踪忽略插件

前言 当使用分布式追踪系统时&#xff0c;有时需要排除某些端点或路径&#xff0c;以减轻追踪系统的负载或减少不必要的数据收集。为了满足这种需求&#xff0c;SkyWalking 提供了一个可选的插件&#xff0c;即 apm-trace-ignore-plugin&#xff0c;它允许自定义需要跳过的路径…...

第十三届蓝桥杯大赛软件赛省赛CC++大学B组

第十三届蓝桥杯大赛软件赛省赛CC 大学 B 组 文章目录 第十三届蓝桥杯大赛软件赛省赛CC 大学 B 组1、九进制转十进制2、顺子日期3、刷题统计4、修建灌木5、x进制减法6、统计子矩阵7、积木画8、扫雷9、李白打酒加强版10、砍竹子 1、九进制转十进制 计算器计算即可。2999292。 2、…...

zookeeper监听集群节点的实现zkclient组件实现方案(Java版)

ZooKeeper Watcher 机制 client 向zookeeper 注册监听client注册的同时会存储一个WatchManager对象向zookeeper发生改变则notification client 并发送一个WatchManager对象,然后client再更新该对象 package com.jacky.zk.demo;import org.I0Itec.zkclient.IZkChildListener;…...

【ArduinoQuartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能

【Arduino&Quartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能 一、将Reindeer软核下载到STEP CYC10&#xff08;一&#xff09;下载PulseRain Reindeer软核&#xff08;二&#xff09;配置Reindeer软核到开发板1.将sof文件转换为jic文件2.将jic文…...

【电路笔记】-逻辑与门

逻辑与门 文章目录 逻辑与门1、概述2、2 输入晶体管与门3、数字与门类型4、7408 四路 2 输入与门逻辑与门是一种数字逻辑电路,仅当其所有输入均为高电平时,其输出才会变为高电平至逻辑电平 1。 1、概述 数字逻辑与门的输出状态仅在其任何输入处于逻辑电平“0”时再次返回“低…...

蓝桥杯练习——拼出一个未来

选中 index.html 右键启动 Web Server 服务&#xff08;Open with Live Server&#xff09;&#xff0c;让项目运行起来。接着&#xff0c;打开环境右侧的【Web 服务】&#xff0c;就可以在浏览器中看到如下效果&#xff1a; 目标 完善 js/index.js 的 TODO 部分&#xff0c;实…...

stm32f103c8t6学习笔记(学习B站up江科大自化协)-SPI

SPI通信 SPI&#xff0c;&#xff08;serial peripheral interface&#xff09;&#xff0c;字面翻译是串行外设接口&#xff0c;是一种通用的数据总线&#xff0c;适用于主控和外挂芯片之间的通信&#xff0c;与IIC应用领域非常相似。 IIC无论是在硬件电路还是在软件时序设计…...

云计算的安全需求

目录 一、概述 二、云安全服务基本能力要求 三、信息安全服务&#xff08;云计算安全类&#xff09;资质要求 3.1 概述 3.2 资质要求内容 3.2.1 组织与管理要求 3.2.2 技术能力要求 四、云安全主要合规要求 4.1 安全管理机构部门的建立 4.2 安全管理规范计划的编制 4…...

【C++】编程规范之表达式原则

表达式中变量的位置 在编写表达式时&#xff0c;将变量放置在右边&#xff0c;可以提高代码的可读性和可理解性。这种做法符合自然语言的阅读习惯&#xff0c;使得代码更易于理解。 // Good if (5 x) {// do something }// Avoid if (x 5) {// do something }不变量和资源申…...

Python人工智能基础知识:理解神经网络与机器学习的基本概念

人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是当今科技领域的热门话题之一&#xff0c;而神经网络和机器学习作为AI的两个重要分支&#xff0c;在解决各种问题中发挥着重要作用。本文将详细介绍神经网络和机器学习的基本概念&#xff0c;帮助读者更…...

10_MVC

文章目录 JSON常用的JSON解析Jackson的常规使用指定日期格式 MVC设计模式MVC介绍前后端分离案例&#xff08;开发与Json相关接口&#xff09; 三层架构三层架构介绍 JSON JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式&#xff0c;是存…...

【Java多线程(4)】案例:设计模式

目录 一、什么是设计模式&#xff1f; 二、单例模式 1. 饿汉模式 2. 懒汉模式 懒汉模式-第一次改进 懒汉模式-第二次改进 懒汉模式-第三次改进 一、什么是设计模式&#xff1f; 设计模式是针对软件设计中常见问题的通用解决方案。它们提供了一种被广泛接受的方法来解决…...

时序预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络时间序列预测

时序预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-BiLST…...

java面试题(4)|Spring和Spring Boot之间有什么关联和区别

文章目录 Spring和Spring Boot的有什么关联&#xff1f;Spring和Spring Boot有什么区别&#xff1f;如何快速区分某个项目采用的是 Spring 还是 Spring Boot&#xff1f; Spring和Spring Boot的有什么关联&#xff1f; Spring Boot是建立在Spring框架之上的&#xff0c;因此它…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...