SpringSecurity集成JWT

使用 Spring Security 集成 JWT(JSON Web Token)身份验证是一种常见的方式来实现基于令牌的身份验证。在 Spring Boot 应用程序中使用 Spring Security 和 JWT,可以创建一个安全、可扩展的身份验证系统。下面是一个示例,展示如何在 Spring Boot 项目中集成 JWT 身份验证:

1. 添加依赖

首先,在你的 pom.xml 中添加与 JWT 和 Spring Security 相关的依赖:

<dependencies><!-- Spring Boot Starter Security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- JJWT (Java JSON Web Token) --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.5</version><scope>runtime</scope></dependency>
</dependencies>

2. 配置 JWT 密钥

application.propertiesapplication.yml 文件中配置用于签署和验证 JWT 的密钥:

properties code

# JWT 配置
jwt.secret=your-secret-key
jwt.expiration-time=86400000 # 令牌有效时间,单位为毫秒
jwt.header=Authorization # JWT 令牌的请求头
jwt.prefix=Bearer # 令牌前缀

3. JWT 工具类

创建一个工具类来生成和解析 JWT:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class JwtTokenUtil {@Value("${jwt.secret}")private String secret;@Value("${jwt.expiration-time}")private long expirationTime;// 生成 JWT 令牌public String generateToken(String username) {Date now = new Date();Date expiryDate = new Date(now.getTime() + expirationTime);return Jwts.builder().setSubject(username).setIssuedAt(now).setExpiration(expiryDate).signWith(SignatureAlgorithm.HS512, secret).compact();}// 解析 JWT 令牌public String getUsernameFromToken(String token) {Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();return claims.getSubject();}// 验证 JWT 令牌是否有效public boolean validateToken(String token, String username) {String tokenUsername = getUsernameFromToken(token);Date expiration = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getExpiration();return (username.equals(tokenUsername) && expiration.after(new Date()));}
}

4. JWT 过滤器

创建一个过滤器,用于在请求中拦截 JWT 令牌,并根据令牌进行身份验证:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {@Autowiredprivate JwtTokenUtil jwtTokenUtil;@Autowiredprivate UserDetailsService userDetailsService;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws ServletException, IOException {String header = request.getHeader("${jwt.header}");if (header != null && header.startsWith("${jwt.prefix} ")) {String token = header.replace("${jwt.prefix} ", "");String username = jwtTokenUtil.getUsernameFromToken(token);if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {UserDetails userDetails = userDetailsService.loadUserByUsername(username);if (jwtTokenUtil.validateToken(token, username)) {UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authentication);}}}chain.doFilter(request, response);}
}

5. 配置 Spring Security

SecurityConfig 中配置 Spring Security 来使用 JWT 过滤器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate JwtAuthenticationFilter jwtAuthenticationFilter;@Autowiredprivate UserDetailsService userDetailsService;@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors().and().csrf().disable().authorizeRequests().antMatchers("/auth/**").permitAll() // 允许未认证访问登录和注册等路径.anyRequest().authenticated() // 其他请求需要身份验证.and().exceptionHandling().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);// 添加 JWT 过滤器http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}

6. 登录和令牌颁发

在控制器中实现登录和令牌颁发:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/auth")
public class AuthController {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate JwtTokenUtil jwtTokenUtil;@Autowiredprivate UserDetailsService userDetailsService;@PostMapping("/login")public ResponseEntity<?> login(@RequestBody AuthRequest authRequest) {try {// 进行身份验证authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword()));// 加载用户详细信息UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());// 生成 JWT 令牌String token = jwtTokenUtil.generateToken(userDetails.getUsername());// 返回令牌return ResponseEntity.ok(new AuthResponse(token));} catch (BadCredentialsException e) {return ResponseEntity.status(401).body("Invalid credentials");}}
}

数据模型:

  • AuthRequest:表示登录请求,包括用户名和密码。
  • AuthResponse:表示登录响应,包括生成的 JWT 令牌。
// 登录请求数据模型
public class AuthRequest {private String username;private String password;// Getters and setters...
}// 登录响应数据模型
public class AuthResponse {private String token;public AuthResponse(String token) {this.token = token;}// Getters and setters...
}

通过以上配置和代码,你可以在 Spring Boot 项目中集成 JWT 身份验证。你可以根据自己的需求进一步定制和优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/1319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

温湿度LCD显示并上传服务器

项目需求 通过温湿度传感器将值传到LCD1602&#xff0c;并实时通过蓝牙透传到手机。 硬件介绍 温湿度传感器 DHT11温湿度传感器 DHT11_温湿度传感器数据格式-CSDN博客 LCD1602LCD1602-CSDN博客 HC-01 继电器模块 硬件接线 LCD1602 D0~D7 --> A0~A7VDD, A --> 5v…

STM32H750外设ADC之双重 ADC 模式

目录 概述 1 双重 ADC 模式介绍 1.1 双重 ADC模式 1.2 双重 ADC 模式的类型 2 双重 ADC 模式寄存器的配置 3 模式功能实现 3.1 注入同步模式 3.2 支持独立注入的常规同步模式 3.2.1 中断的方式 3.2.2 DMA 读取常规数据 3.3 支持独立注入的交替模式 3.3.1 中断触发…

色彩的魔力:渐变色在设计中的无限可能性

夕阳&#xff0c;天空&#xff0c;湖面&#xff0c;夕阳...随着距离和光影的变化&#xff0c;颜色的渐变色&#xff0c;近大远小、近实远虚的透视&#xff0c;为大自然营造了浪漫的氛围。延伸到UI/UX设计领域&#xff0c;这种现实、惊艳、独特的渐变色也深受众多设计师的喜爱。…

setmapAVL树红黑树

目录 关联式容器树形结构的关联式容器setset的模板参数列表set的构造函数set的迭代器set的容量操作set其他操作 multisetmap键值对map的模板参数列表map的迭代器map中元素的修改map的容量与元素访问 multimap底层结构avl树avl树概念AVL树结点的定义AVL树的插入AVL树的旋转AVL树…

python-flask结合bootstrap实现网页小工具实例-半小时速通版

参考&#xff1a; Python之flask结合Bootstrap框架快速搭建Web应用_支持bootstrap的python软件-CSDN博客 https://blog.csdn.net/lovedingd/article/details/106696832 Bootstrap 警告框 | 菜鸟教程 https://www.runoob.com/bootstrap/bootstrap-alert-plugin.html flask框架…

数据结构——7.3 树形查找

7.3 树形查找 概念 二叉排序树&#xff08;BST&#xff09; 二叉排序树&#xff08;Binary Sort Tree&#xff0c;BST&#xff09;&#xff0c;又称为二叉查找&#xff08;搜索&#xff09;树&#xff08;Binary Search Tree&#xff09;&#xff0c;是一种特殊的二叉树&am…

FreeLearning C/C++ 译文集翻译完成

C 高级编程C 高级编程秘籍Qt Creator 应用开发C 游戏编程入门指南C 编程入门指南Boost.Asio C 网络编程Boost C 应用开发秘籍第二版C 数据结构与算法设计原理C Qt5 GUI 编程C 高性能编程C 反应式编程C 系统编程秘籍C 研讨会C 现代嵌入式编程秘籍C 专家编程&#xff1a;成为熟练…

Android,判断是否快速点击

问题背景 在Android控件中,如果快速点击容易造成一些不同的bug,尤其是那种在click事件中方有耗时操作的代码,容易引起anr,并且有些性能低的机器,在用户点击多次控件的时候很容易出现问题,在车机中也会导致回弹的一系列问题(这里面包括get到的信号导致回弹),针对于这种…

力扣---从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]示…

Rust常用特型之Borrow和BorrowMut特型

在Rust标准库中&#xff0c;存在很多常用的工具类特型&#xff0c;它们能帮助我们写出更具有Rust风格的代码。 std::borrow::Borrow和AsRef有点相似&#xff0c;如果一个类型实现了Borrow<T>&#xff0c;那么你可以从它的borrow函数里高效的借出一个&T。但是Borrow施…

synchronized和ReentrantLock傻傻分不清楚

synchronized和ReentrantLock都是用于线程间同步的机制&#xff0c;都是可重入锁&#xff08;同一个线程可以多次获取同一个锁&#xff09;&#xff0c;它们的异同点如下&#xff1a; 一、应用场景 1.synchronized可应用于实例方法、静态方法和代码块。 2.ReentrantLock 是 jav…

使用Docker搭建Redis主从集群

文章目录 ☃️前言☃️搭建❄️❄️架构❄️❄️实例说明❄️❄️搭建第一个服务器上的两个实例❄️❄️搭建第二个服务器上的一个实例 ☃️开启主从❄️❄️改配置❄️❄️重启从节点 ☃️验证 ☃️前言 单节点 Redis 的并发能力是有上限的&#xff0c;要进一步提高Redis的并…

了解监控易(33):工单管理

在复杂的IT运维环境中&#xff0c;高效、规范地处理各种事务请求至关重要。监控易的工单管理功能&#xff0c;作为一款轻量化的运维协同工具&#xff0c;为团队提供了一个集中化、标准化的平台&#xff0c;以创建、接单、转交、挂起和重启工单&#xff0c;从而确保客户设备故障…

搜维尔科技:SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中

SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中 搜维尔科技&#xff1a;SenseGlove 的 Nova 被用于组装卫星接收器的虚拟现实培训项目中 得益于 SenseGlove 的力反馈专利&#xff0c;学员可以感受到他们正在组装的零件的形状、尺寸和密度。学员可以通过运动跟踪…

[大模型]TransNormerLLM-7B FastApi 部署调用

TransNormerLLM-7B FastApi 部署调用 1. TransNormer 介绍 TransNormerLLM 是一个基于线性注意力的 LLM&#xff0c;在准确性和效率方面均优于传统的基于 softmax 注意力的模型。它是在包含多达1.4 万亿个令牌的高质量语料库上进行训练的&#xff0c;TransNormerLLM 从之前的…

K-means和DBSCAN

目录 一、K-means和DBSCAN之间的主要区别 二、DBSCAN聚类算法 2.1DBSCAN聚类算法实现点集数据的聚类 2.2DBSCAN聚类算法实现鸢尾花数据集的聚类 三、K-means聚类算法 3.1K-means聚类算法实现随机数据的聚类 3.2K-means聚类算法实现鸢尾花数据集的聚类 一、K-means和DBSC…

014Node.js时间格式包silly-datetime安装与使用

下载&#xff1a; https://www.npmjs.com/网站上下载silly-datetime 安装 npm i silly-datetime --save var sd require(silly-datetime);console.log(new Date()); //2024-04-18T04:40:38.505Zvar dsd.format(new Date(), YYYY-MM-DD HH:mm);console.log(d); //2024…

未加权的相位解包裹算法DCT-0基础入门(含matlab代码和详细教程解析)

后面会更新c++ 的代码 ! phi = phase_unwrap(psi, weight) % get the wrapped differences of the wrapped valuesdx = [zeros([size(psi,1),1]), wrapToPi(diff(psi, 1, 2)), zeros([size(psi,1),1])];dy = [zeros([1,size(psi,2)]); wrapToPi(diff(psi, 1, 1)); zeros([1,s…

idea在controller或者service使用ctrl+alt+b进入方法后,如何返回到 进入前的那一层

idea在controller或者service使用ctrlaltb进入方法后&#xff0c;如何返回到进入方法的最外层 解决方案使用 ctrlalt ← /→← /→ 键盘上的左右键盘

jQuery 选择器有几种,分别是什么

jQuery选择器是用于“选择”&#xff08;或查找&#xff09;HTML元素的强大工具。jQuery选择器基于元素的名称、ID、类、类型、属性等进行选择。以下是jQuery选择器的几种主要类型&#xff0c;以及它们的详细代码示例&#xff1a; 基本选择器&#xff1a; 元素选择器&#xff1…