Spring Security 配置简明教程:从 WebSecurityConfigurerAdapter 到新方法

1,274 阅读2分钟

简介

Spring Security 是一个强大的安全框架,用于保护 Web 应用程序。从 Spring Security 5.7.0-M2 开始,WebSecurityConfigurerAdapter 被废弃,推荐使用基于组件的安全配置方法。本文将介绍如何使用 WebSecurityConfigurerAdapter 以及如何迁移到新方法。

WebSecurityConfigurerAdapter 的用法

1. 基本配置

WebSecurityConfigurerAdapter 可以配置各种安全功能,如身份验证、授权、CSRF 等。

java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 允许访问 /public/** 的所有请求
        http.authorizeRequests()
            .antMatchers("/public/**").permitAll()
            // 其他请求需要身份验证
            .anyRequest().authenticated()
            .and()
            // 启用表单登录
            .formLogin();
    }
}

2. 身份验证配置

可以通过 configure(AuthenticationManagerBuilder) 方法配置身份验证。

java
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // 内存中存储用户信息
    auth.inMemoryAuthentication()
        .withUser("user")
        .password("password")
        .roles("USER");
}

3. 忽略某些请求

可以通过 configure(WebSecurity) 方法忽略某些请求。

java
@Override
public void configure(WebSecurity web) throws Exception {
    // 忽略 /ignore1 和 /ignore2 的请求
    web.ignoring().antMatchers("/ignore1", "/ignore2");
}

迁移到新方法

1. 使用 SecurityFilterChain

在 Spring Security 5.4 及后续版本中,可以通过创建 SecurityFilterChain bean 来配置安全性。

java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 配置请求授权
        http.authorizeHttpRequests(auth -> auth
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
        );
        return http.build();
    }
}

2. 使用 WebSecurityCustomizer

可以通过 WebSecurityCustomizer 忽略某些请求。

java
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}

3. 身份验证配置

身份验证配置可以通过 AuthenticationManagerBuilder 来实现。

java
@Bean
public AuthenticationManager authenticationManagerBean(HttpSecurity http) throws Exception {
    // 获取共享的 AuthenticationManagerBuilder
    AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
    // 配置用户服务和密码编码器
    authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    return authenticationManagerBuilder.build();
}

案例:完整的配置示例

以下是一个完整的配置示例,包括请求授权、身份验证和忽略请求:

java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
        );
        http.formLogin();
        return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
    }

    @Bean
    public AuthenticationManager authenticationManagerBean(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
        return authenticationManagerBuilder.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        // 自定义用户服务实现
        return new CustomUserDetailsService();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 使用 BCryptPasswordEncoder
        return new BCryptPasswordEncoder();
    }
}