Configuration Migrations

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

The following steps relate to changes around how to configure HttpSecurity, WebSecurity and related components.

Use the Lambda DSL

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

The Lambda DSL is present in Spring Security since version 5.2, and it allows HTTP security to be configured using lambdas.

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

You may have seen this style of configuration in the Spring Security documentation or samples. Let us take a look at how a lambda configuration of HTTP security compares to the previous configuration style.

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。这样做主要有几个原因:

The Lambda DSL is the preferred way to configure Spring Security, the prior configuration style will not be valid in Spring Security 7 where the usage of the Lambda DSL will be required. This has been done mainly for a couple of reasons:

  • The previous way it was not clear what object was getting configured without knowing what the return type was. The deeper the nesting the more confusing it became. Even experienced users would think that their configuration was doing one thing when in fact, it was doing something else.

  • Consistency. Many code bases switched between the two styles which caused inconsistencies that made understanding the configuration difficult and often led to misconfigurations.

Lambda DSL Configuration Tips

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

When comparing the two samples above, you will notice some key differences:

  • In the Lambda DSL there is no need to chain configuration options using the .and() method. The HttpSecurity instance is automatically returned for further configuration after the call to the lambda method.

  • Customizer.withDefaults() enables a security feature using the defaults provided by Spring Security. This is a shortcut for the lambda expression it → {}.

WebFlux Security

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

You may also configure WebFlux security using lambdas in a similar manner. Below is an example configuration using lambdas.

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 的创建是为了实现以下目标:

The Lambda DSL was created to accomplish to following goals:

  • Automatic indentation makes the configuration more readable.

  • There is no need to chain configuration options using .and()

  • The Spring Security DSL has a similar configuration style to other Spring DSLs such as Spring Integration and 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

In versions prior to 6.2, if you had a custom DSL, you would apply it to the HttpSecurity using the HttpSecurity#apply(…​) method. However, starting from version 6.2, this method is deprecated and will be removed in 7.0 because it will no longer be possible to chain configurations using .and() once .and() is removed (see [role="bare"]https://github.com/spring-projects/spring-security/issues/13067). Instead, it is recommended to use the new .with(…​) method. For more information about how to use .with(…​) please refer to the Custom DSLs section.