如何将已弃用的 WebSecurityConfigurerAdapter 迁移到 SecurityFilterChain?

How to migrate deprecated WebSecurityConfigurerAdapter to SecurityFilterChain?

正如他们对我们的描述 hereWebSecurityConfigurerAdapter 将在一段时间后弃用。

我尝试用 SecurityFilterChain 重构 WebSecurityConfigurerAdapter 的实现,因为我想实现 JWT 模式。 我面临的主要考虑是 returns void.

中的配置
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(authenticationManagerBean(), accessTokenExpiredInDays, refreshTokenExpiredInDays, jwtSecret);
    customAuthenticationFilter.setFilterProcessesUrl("/api/login");
    http
        .csrf().disable();
    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http
        .authorizeRequests()
            .antMatchers("/error").permitAll();
    http
        .authorizeRequests()
            .antMatchers("/api/login/**", "/api/token/refresh/**").permitAll();
    http
        .authorizeRequests()
            .anyRequest().authenticated();
    http
        .addFilter(customAuthenticationFilter);
    http
        .addFilterBefore(new CustomAuthorizationFilter(jwtSecret), UsernamePasswordAuthenticationFilter.class);
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
    return super.authenticationManagerBean();
}

请注意,Spring 安全性 built-in 支持 JWT 身份验证,无需创建自定义过滤器。 您可以找到 Spring 安全团队 here.

提供的示例

但是,如果您选择创建自定义过滤器,建议的配置方法是创建 custom DSL
这与 Spring 安全部门在内部执行的方式相同。

我已经使用自定义 DSL 重写了您的配置。

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable();
    http
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http
        .authorizeRequests()
        .antMatchers("/error").permitAll();
    http
        .authorizeRequests()
        .antMatchers("/api/login/**", "/api/token/refresh/**").permitAll();
    http
        .authorizeRequests()
        .anyRequest().authenticated();
    // apply the custom DSL which adds the custom filter
    http
        .apply(customDsl());
    http
        .addFilterBefore(new CustomAuthorizationFilter(jwtSecret), UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        AuthenticationManager authenticationManager =
                http.getSharedObject(AuthenticationManager.class);
        CustomAuthenticationFilter filter = 
                new CustomAuthenticationFilter(authenticationManager, accessTokenExpiredInDays, refreshTokenExpiredInDays, jwtSecret);
        filter.setFilterProcessesUrl("/api/login");
        http.addFilter(filter);
    }

    public static MyCustomDsl customDsl() {
        return new MyCustomDsl();
    }
}

此配置以及其他示例在 Spring blog post 中关于从 WebSecurityConfigurerAdapter 迁移的描述。