Spring Security 是 Spring 框架的 安全管理 模块,主要用于身份认证(Authentication) 和 授权(Authorization),并提供多种安全防护,如:
Spring Security 主要由 过滤器链(SecurityFilterChain) 组成,每个请求都会经过这些过滤器来执行安全检查:
请求 -> SecurityFilterChain -> 认证 -> 授权 -> 访问控制 -> 处理请求其中 核心组件:
在 pom.xml 中引入 Spring Security:
<dependencies>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Data JPA(用于数据库存储用户) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database(内存数据库) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>Spring Security 默认开启:
Using generated security password: e3f7e4b9-4d15-4f34-a8b9-9c845bc3c1dc
/logout 即可退出。如何自定义 Spring Security 逻辑? 需要进行 配置。
package com.example.security.entity;
import jakarta.persistence.*;
import lombok.Data;
@Entity
@Table(name = "users")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String role; // 角色(如 ROLE_USER、ROLE_ADMIN)
}2. 创建 UserRepository
package com.example.security.repository;
import com.example.security.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}Spring Security 需要获取用户信息,使用 UserDetailsService 进行查询:
package com.example.security.service;
import com.example.security.entity.User;
import com.example.security.repository.UserRepository;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserService implements UserDetailsService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("用户未找到"));
return org.springframework.security.core.userdetails.User
.withUsername(user.getUsername())
.password(user.getPassword())
.roles(user.getRole()) // 角色
.build();
}
}package com.example.security.config;
import com.example.security.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final UserService userService;
public SecurityConfig(UserService userService) {
this.userService = userService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
)
.formLogin()
.and()
.logout();
return http.build();
}
}为了让 Spring Security 支持无状态认证,我们可以使用 JWT(JSON Web Token):
package com.example.security.util;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtil {
private final String secretKey = "mySecretKey";
private final long expiration = 1000 * 60 * 60;
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
public String extractUsername(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
}
}如果这篇 Spring Security 终极指南 对你有帮助,别忘了 点赞 👍、收藏 ⭐、评论 📝 支持一下!你的支持是我持续更新优质技术内容的最大动力!🚀
如果你在 Spring Security 实践过程中遇到问题,欢迎留言讨论,我会第一时间回复!💬 一起进步,一起精通!💪