Spring Cloud Security集成JWT 快速入门Demo

server/2025/1/8 20:25:17/

一、介绍

JWT (JSON Web Token) 是一种带有绑实和信息的简单标准化机制,在信息通信中用于验证和信息传递。尤其在应用中使用Spring Cloud实现分布式构建时,JWT可以作为一种无状态验证原理的证明。 本文将进一步描述如何在Spring Cloud Security中集成JWT,包括原理和完整实现过程。

二、JWT原理

JWT包括三部分:

  1. Header (头):指定算法和格式(如HS256)。
  2. Payload (资料):包含用户信息和自定义预设背景信息(如用户id和身份)。
  3. Signature (签名):通过Header和Payload实现数据加密,用于验证数据的绑实性。

处理流程:

  1. 服务器在用户登录后生成JWT并下发。
  2. 用户进行请求时,附上JWT。
  3. 服务器校验JWT签名,验证成功则完成请求。

三、运行环境和添加依赖

需要以Spring Boot为基础,以Spring Security和Spring Cloud为核心,并使用jjwt库实现JWT功能。 添加依赖: 在Maven项目的pom.xml中添加依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>spring-cloud-security</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><spring-security.version>6.3.3</spring-security.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><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></project>

四、实现JWT

1. 配置文件
sever:port: 8080
2. 创建JWT功能类

创建JwtUtil

package com.et;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component;import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@Component
public class JwtUtil {private final SecretKey secretKey;// Initialize the secret key using a secure key generation methodpublic JwtUtil() {this.secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);}public String generateToken(String username) {Map<String, Object> claims = new HashMap<>();return doGenerateToken(claims, username);}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() + 3600 * 1000)) // 1 hour expiration.signWith(secretKey).compact();}public boolean validateToken(String token) {try {Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);return true;} catch (Exception e) {return false;}}public String getUsernameFromToken(String token) {Claims claims = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token).getBody();return claims.getSubject();}
}
3. 配置应用Security策略

创建JwtFilter

package com.et;import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;import java.io.IOException;
import java.util.Collection;
@Component
public class JwtFilter extends OncePerRequestFilter {private final JwtUtil jwtUtil;private final UserDetailsService userDetailsService;public JwtFilter(JwtUtil jwtUtil, UserDetailsService userDetailsService) {this.jwtUtil = jwtUtil;this.userDetailsService = userDetailsService;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, ServletException {String header = request.getHeader("Authorization");if (header != null && header.startsWith("Bearer ")) {String token = header.substring(7);if (jwtUtil.validateToken(token)) {String username = jwtUtil.getUsernameFromToken(token);UserDetails userDetails = userDetailsService.loadUserByUsername(username);Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();SecurityContextHolder.getContext().setAuthentication(new JwtAuthenticationToken(userDetails,authorities));}}filterChain.doFilter(request, response);}
}

在SecurityConfig中配置JWT过滤器:

package com.et;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.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;@Configuration
@EnableWebSecurity
public class SecurityConfig {private final JwtFilter jwtFilter;public SecurityConfig(JwtFilter jwtFilter) {this.jwtFilter = jwtFilter;}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().requestMatchers("/auth/login", "/auth/register").permitAll().anyRequest().authenticated().and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);return http.build();}@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {return authenticationConfiguration.getAuthenticationManager();}
}

 controller

package com.et;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/auth")
public class AuthController {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate JwtUtil jwtUtil;@PostMapping("/login")public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {try {authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));String token = jwtUtil.generateToken(loginRequest.getUsername());return ResponseEntity.ok(new JwtResponse(token));} catch (Exception e) {e.printStackTrace();return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");}}@PostMapping("/register")public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {return ResponseEntity.ok("User registered successfully");}@PostMapping("/api")public String api() {return "api ......";}
}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springcloud-demo(Spring Cloud Security)

五、测试

通过/login进行登录,生成JWT

token

在后端api请求时附上这个JWT(如「Authorization: Bearer 」),确保服务器校验成功。

api


http://www.ppmy.cn/server/156874.html

相关文章

WebSocket底层原理及 java 应用

WebSocket 底层原理 1. WebSocket 协议的基本原理 WebSocket 是一个在客户端和服务器之间建立持久、全双工的连接的协议。与传统的 HTTP 请求/响应模型不同&#xff0c;WebSocket 允许客户端和服务器双方通过一个持久的连接进行双向通信。 1.1 WebSocket 握手过程 WebSocke…

线性代数考研笔记

行列式 背景 分子行列式&#xff1a;求哪个未知数&#xff0c;就把b1&#xff0c;b2放在对应的位置 分母行列式&#xff1a;系数对应写即可 全排列与逆序数 1 3 2&#xff1a;逆序数为1 奇排列 1 2 3&#xff1a;逆序数为0 偶排列 将 1 3 2 只需将3 2交换1次就可以还原原…

对话|全年HUD前装将超330万台,疆程技术瞄准人机交互“第一屏”

2024年&#xff0c;在高阶智驾进入快速上车的同时&#xff0c;座舱人机交互也在迎来新的增长点。Chat GPT、AR-HUD、车载投影等新配置都在带来新增量机会。 高工智能汽车研究院监测数据显示&#xff0c;2024年1-10月&#xff0c;中国市场&#xff08;不含进出口&#xff09;乘用…

win10 VS2019上libtorch库配置过程

win10 VS2019上libtorch库配置过程 0 引言1 获取libtorch2 在VS上配置使用libtorch库3 结语 0 引言 &#x1f4bb;&#x1f4bb;AI一下&#x1f4bb;&#x1f4bb;   libtorch库是一个用于深度学习的C库&#xff0c;是PyTorch的官方C前端。它提供了用于构建和训练深度学习模…

数据结构与算法之排序

9.1 排序的概念 1. 排序的定义 定义&#xff1a;排序是将表中的记录按关键字递增&#xff08;或递减&#xff09;有序排列的过程。说明&#xff1a;数据中可以存在相同关键字的记录。本章主要考虑递增排序。扩展&#xff1a;排序是数据处理中的基本操作之一&#xff0c;广泛应用…

学英语学压测:02jmeter组件-测试计划和线程组ramp-up参数的作用

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#xff1a;先看关键单词&#xff0c;再看英文&#xff0c;最后看中文总结&#xff0c;再回头看一遍英文原文&#xff0c;效果更佳&#xff01;&#xff01; 关键词 Functional Testing功能测试[ˈfʌŋkʃənəl ˈtɛstɪŋ]Sample样…

SpringBoot安装及配置

1 Spring Boot介绍 Spring让Java程序更加快速, 简单和安全. Spring对于速度、简单性和⽣产⼒的关注使其成为世界上最流⾏的Java框架。 这些项⽬都是基于Spring Framework来进⾏开发的, 但是Spring Framework存在配置多, ⼊⻔难的问题, Spring 也意识到了这个问题, 为了简化开…

电脑硬盘系统迁移及问题处理

一、系统迁移准备 1、确认你的电脑主板是否支持安装两块硬盘,如电脑主板有多个M2硬盘接口,我们将新硬盘安装到主板上,原来的老硬盘安装在第二个接口上,主板只有一个M2接口的话可以使用移动硬盘盒。 2、新硬盘安装好后,我们进入原来的系统,在 此电脑–右键–管理–磁盘管…