Configuration Migrations

以下步骤涉及如何配置 HttpSecurityWebSecurity 和相关组件的变化。

Use the Lambda DSL

自 5.2 版起,Spring Security 中包含 Lambda DSL,它允许使用 lambda 来配置 HTTP 安全。

你可能在 Spring Security 文档或示例中看到过这种配置样式。让我们来看看 HTTP 安全的 lambda 配置与之前的配置样式相比有何不同。

Configuration using lambdas
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/blog/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(formLogin -> formLogin
                .loginPage("/login")
                .permitAll()
            )
            .rememberMe(Customizer.withDefaults());

        return http.build();
    }
}
Equivalent configuration without using lambdas
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests()
                .requestMatchers("/blog/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .rememberMe();

        return http.build();
    }
}

Lambda DSL 是配置 Spring Security 的首选方法,在 Spring Security 7 中,之前的配置样式将无效,Spring Security 7 要求使用 Lambda DSL。这样做主要有几个原因:

  • 之前的方式不够明确,不知道返回类型是什么,所以不知道正在配置哪个对象。嵌套得越深,就越令人困惑。即使是经验丰富的用户也会认为他们的配置做了一件事,但实际上却做了另一件事。

  • 一致性。很多代码库在这两种风格之间切换,导致了不一致,从而难以理解配置,而且还经常导致错误配置。

Lambda DSL Configuration Tips

比较上述两个示例时,你会注意到一些关键差异:

  • 在 Lambda DSL 中,无需使用 .and() 方法来链接配置选项。在调用 lambda 方法之后,会自动返回 HttpSecurity 实例以便进行进一步的配置。

  • Customizer.withDefaults() 使用 Spring Security 提供的默认值来启用安全功能。这是一个对 lambda 表达式 it → {} 的快捷方式。

WebFlux Security

你还可以类似地使用 lambda 配置 WebFlux 安全。以下是使用 lambda 的示例配置。

WebFlux configuration using lambdas
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange(exchanges -> exchanges
                .pathMatchers("/blog/**").permitAll()
                .anyExchange().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .formLogin(formLogin -> formLogin
                .loginPage("/login")
            );

        return http.build();
    }

}

Goals of the Lambda DSL

Lambda DSL 的创建是为了实现以下目标:

  • 自动缩进使配置更易读。

  • 无需使用 `.and()`链接配置选项

  • Spring Security DSL 的配置风格与其他 Spring DSL(例如 Spring Integration 和 Spring Cloud Gateway)类似。

Use .with() instead of .apply() for Custom DSLs

在 6.2 之前的版本中,如果您有一个 custom DSL,您需要使用 HttpSecurity#apply(…​) 方法将其应用到 HttpSecurity。但是,从版本 6.2 开始,此方法已弃用,并且将在 7.0 中删除,因为一旦删除 .and(),就不再可能使用 .and() 来链接配置(参见 [role="bare"][role="bare"]https://github.com/spring-projects/spring-security/issues/13067)。相反,建议使用新的 .with(…​) 方法。有关如何使用 .with(…​) 的详细信息,请参阅 Custom DSLs section