1. SpringSecurity基础配置入门
SpringSecurity作为Spring生态中的安全框架,其核心配置类WebSecurityConfigurerAdapter是权限管理的入口。我们先从最基础的配置开始:
java复制@Configuration
@EnableWebSecurity
public class BasicSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
}
这段配置实现了:
- 所有请求都需要认证
- 启用表单登录
- 启用HTTP基本认证
注意:SpringBoot 2.7+版本开始,WebSecurityConfigurerAdapter已被标记为过时,推荐使用组件式配置。但理解这种配置方式仍是掌握SpringSecurity的基础。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 密码编码器配置
密码安全是系统安全的第一道防线,SpringSecurity要求必须明确指定密码编码器:
java复制@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// 在内存中配置用户示例
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(passwordEncoder().encode("123456"))
.roles("ADMIN");
}
实际项目中常见的密码编码器对比:
| 编码器类型 | 特点 | 适用场景 |
|---|---|---|
| BCrypt | 自适应哈希,内置盐值 | 推荐首选 |
| Argon2 | 抗GPU/ASIC破解 | 高安全要求 |
| PBKDF2 | 可配置迭代次数 | 兼容老系统 |
| SCrypt | 内存密集型 | 防硬件破解 |
3. 自定义登录配置
3.1 表单登录定制
java复制@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/custom-login") // 自定义登录页
.loginProcessingUrl("/auth") // 认证处理URL
.defaultSuccessUrl("/home", true)
.failureUrl("/login?error=true")
.usernameParameter("uname")
.passwordParameter("pwd");
}
关键点说明:
loginPage:当未认证用户尝试访问受保护资源时,重定向到此页面loginProcessingUrl:需要与表单的action属性一致defaultSuccessUrl的第二个参数强制重定向,避免登录后返回原请求页
3.2 前后端分离的JSON登录
java复制// 配置类
http
.formLogin()
.successHandler(jsonAuthSuccessHandler)
.failureHandler(jsonAuthFailureHandler);
// 成功处理器
@Component
public class JsonAuthSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(...) {
response.setContentType("application/json");
response.getWriter().write(
"{\"code\":200,\"message\":\"登录成功\"}"
);
}
}
4. 权限控制配置
4.1 URL级别权限
java复制http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/api/**").access("hasIpAddress('192.168.1.0/24')")
.anyRequest().authenticated();
路径匹配规则优先级:
- 具体路径优先于通配符路径
- 长路径优先于短路径
- 声明顺序影响匹配结果
4.2 方法级别权限
启用注解支持:
java复制@Configuration
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true
)
public class MethodSecurityConfig {
}
使用示例:
java复制@PreAuthorize("hasRole('ADMIN') or #userId == authentication.principal.id")
public User getUser(Long userId) {
// ...
}
@PostFilter("filterObject.owner == authentication.name")
public List<Document> getDocuments() {
// ...
}
5. 高级安全配置
5.1 CSRF防护
默认开启的CSRF防护需要特别注意:
java复制http.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers("/api/external/**");
REST API常见处理方案:
- 使用X-CSRF-TOKEN头
- 对无状态API禁用CSRF
- 将token存入Cookie而非Session
5.2 CORS配置
java复制@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("https://trusted.com"));
config.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
5.3 会话管理
java复制http.sessionManagement()
.sessionFixation().migrateSession()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.expiredUrl("/session-expired");
会话保护策略对比:
| 策略 | 描述 | 安全级别 |
|---|---|---|
| none | 不做任何改变 | 低 |
| newSession | 创建新会话 | 中 |
| migrateSession | 迁移属性到新会话 | 高 |
| changeSessionId | 使用容器提供的保护 | 中 |
6. 生产环境最佳实践
6.1 安全头配置
java复制http.headers()
.contentSecurityPolicy("default-src 'self'")
.frameOptions().sameOrigin()
.xssProtection().block(true)
.httpStrictTransportSecurity()
.includeSubDomains(true)
.maxAgeInSeconds(31536000);
6.2 审计日志
java复制@Bean
public AuditLogger auditLogger() {
return new DefaultAuditLogger() {
@Override
public void audit(AuditEvent event) {
// 记录到ELK等系统
}
};
}
6.3 性能优化建议
- 使用
@EnableWebSecurity(debug = false) - 避免频繁调用
PasswordEncoder.matches() - 对静态资源配置忽略规则:
java复制web.ignoring().antMatchers("/static/**", "/favicon.ico");
7. 常见问题排查
7.1 登录循环问题
可能原因:
- 未正确配置登录页权限
- 成功处理器逻辑错误
- 会话配置冲突
解决方案:
java复制// 确保登录页可匿名访问
http.authorizeRequests()
.antMatchers("/login").permitAll();
7.2 权限不生效
检查步骤:
- 确认
@EnableGlobalMethodSecurity已启用 - 检查方法上的注解拼写
- 验证角色前缀配置(默认需要"ROLE_"前缀)
7.3 静态资源被拦截
完整解决方案:
java复制@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/static/**");
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
SpringSecurity的配置既需要理解安全原理,又需要掌握框架特性。建议从简单配置开始,逐步增加安全控制,并通过日志观察过滤器链的执行过程。生产环境中,还应定期进行安全审计和渗透测试,确保配置的有效性。
