一定要熟悉spring security原理和jwt无状态原理,理解了才知道代码作用。
在 Spring Security + JWT 认证流程中,通常的做法是:
- 用户提交用户名和密码
- Spring Security 认证管理器 (
AuthenticationManager
) 进行认证 - 如果认证成功,生成 JWT Token 并返回给用户
更详细一点
-
用户首次登录
- 发送
POST /login
请求,携带用户名 + 密码
authenticationManager.authenticate()
认证成功后,返回JWT
- 前端存储
JWT
(通常是localStorage
或sessionStorage
)
- 发送
-
用户访问受保护接口
- 前端在
Authorization
头中附带Bearer Token
- 过滤器
JWTFilter
解析JWT
,从数据库
加载UserDetails
SecurityContextHolder.setAuthentication()
认证成功,继续访问资源。
- 前端在
参考链接有:
spring security 超详细使用教程(接入springboot、前后端分离) - 小程xy - 博客园
SpringSecurity+jwt实现权限认证功能_spring security + jwt-CSDN博客
1.引入相关依赖。我使用的是springboot3.3.5 springsecurity是6.x的 jwt 0.12.6
<dependencies>
<!--用于数据加密,默认启用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
</dependencies>
<!--依赖集中管理-->
<dependencyManagement>
<dependencies>
<!-- 使用jwt进行token验证,包括了三个依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.12.6</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<dependencies>
</dependencyManagement>
2.配置SecurityConfig.java
package com.x.x.x.config;
import com.x.x.x.filter.CustomFilter;
import com.x.x.x.filter.JwtAuthenticationTokenFilter;
import com.x.x.x.security.service.impl.UserDetailsServiceImpl;
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.configurers.SessionManagementConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig {
//customfilter是直接引入使用,jwt过滤器使用了@Compent自动注册为bean了要引入
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
/**
* 用户名和密码也可以在application.properties中设置。
* @return
*/
@Bean
public UserDetailsService userDetailsService() {
// 创建基于内存的用户信息管理器
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
// 创建UserDetails对象,用于管理用户名、用户密码、用户角色、用户权限等内容
manager.createUser(
User.withUsername("admin").password("yourpassword").roles("ADMIN").build()
);
return manager;
}
/**
* 认证管理。 jwt的用户验证
* @param authConfig
* @return
* @throws Exception
*/
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
/**
* 密码加码
* @return
*/
@Bean
public PasswordEncoder passwordEncoder() {
// 也可用有参构造,取值范围是 4 到 31,默认值为 10。数值越大,加密计算越复杂
return new BCryptPasswordEncoder();
}
/**
* 配置过滤链
* 配置自