Spring Security 基础
约 794 字大约 3 分钟
布欧-Lewyon
2026-05-15
首页 › Spring Boot › 安全入门 › Spring Security 基础
Spring Security 为应用提供认证与授权能力。本节覆盖依赖、最小安全配置、用户管理和方法级别安全,让你能快速为 REST API 添加安全防护。
起步依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>引入后立刻生效:
- 所有端点需要登录
- 自动生成一个随机密码(启动日志中打印:
Using generated security password: xxxxxx) - 默认用户名为
user
不用于生产,仅确认集成成功。
最小安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll() // 公开接口
.requestMatchers("/api/admin/**").hasRole("ADMIN") // 仅管理员
.anyRequest().authenticated() // 其余需认证
)
.formLogin(Customizer.withDefaults()) // 表单登录
.httpBasic(Customizer.withDefaults()); // HTTP Basic
return http.build();
}
}禁用 CSRF(REST API 场景)
REST API 使用 Token / JWT 认证而非 Session,应禁用 CSRF:
http.csrf(csrf -> csrf.disable());完整示例
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}内存用户(学习/测试)
@Bean
public UserDetailsService users() {
UserDetails user = User.builder()
.username("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN", "USER")
.build();
return new InMemoryUserDetailsManager(user, admin);
}生产环境应从数据库读取用户信息,使用 UserDetailsService 自定义实现。
在 Controller 中获取当前用户
@RestController
@RequestMapping("/api")
public class ProfileController {
@GetMapping("/me")
public Map<String, Object> currentUser(
@AuthenticationPrincipal UserDetails userDetails) {
return Map.of(
"username", userDetails.getUsername(),
"authorities", userDetails.getAuthorities()
);
}
}也可以通过 SecurityContextHolder:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();密码存储
生产意识:
BCryptPasswordEncoder默认 strength = 10(即 2^10 轮哈希),对 2026 年的硬件来说偏弱但不至于太慢。如果用户注册量极高,可以尝试验证Argon2PasswordEncoder(内存硬算法,抗 GPU 并行攻击更强)。注意:PasswordEncoder切换后,已有用户的密码哈希不会失效——Spring Security 支持DelegatingPasswordEncoder根据存储的前缀选择对应编码器,从而实现无痛迁移。
方法级别安全
@SpringBootApplication
@EnableMethodSecurity // 开启 @PreAuthorize 等注解
public class DemoApplication { ... }@RestController
@RequestMapping("/api/admin")
public class AdminController {
@PreAuthorize("hasRole('ADMIN')")
@DeleteMapping("/users/{id}")
public Result<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return Result.success(null);
}
@PreAuthorize("hasAuthority('user:write')")
@PutMapping("/users/{id}")
public Result<User> updateUser(@PathVariable Long id, @RequestBody User user) {
return Result.success(userService.update(id, user));
}
}小结
spring-boot-starter-security引入后自动保护所有端点,默认用户名user,密码在启动日志中。SecurityFilterChain声明安全规则:permitAll公开、hasRole鉴权、authenticated需登录。- REST API 通常禁用 CSRF,使用无状态 Session 策略。
@EnableMethodSecurity+@PreAuthorize在方法级别精细控制权限。- 易错:密码必须使用
PasswordEncoder编码(BCryptPasswordEncoder),存储明文密码会抛出IllegalArgumentException。requestMatchers的规则顺序很重要——较具体的规则写在前。 - 思考任务:为应用添加 Spring Security,配置
/api/public/**可匿名访问,其余接口需要登录。创建内存用户(user/password),用 curl 验证认证前后的访问行为。
进阶读者:内部架构分析见 Spring Security 进阶:过滤器链与认证流程源码分析。
上一节:Logback 配置
下一节:生产部署
