組態遷移

以下步驟與如何組態 HttpSecurityWebSecurity 和相關組件的變更有關。

使用 Lambda DSL

Lambda DSL 自 Spring Security 5.2 版起已存在,它允許使用 lambda 組態 HTTP 安全性。

您可能在 Spring Security 文件或範例中看過這種組態樣式。讓我們看看 HTTP 安全性的 lambda 組態與先前的組態樣式有何不同。

使用 lambda 的組態
@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();
    }
}
不使用 lambda 的等效組態
@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 中將不再有效,屆時將需要使用 Lambda DSL。這樣做的主要原因有以下幾個

  • 先前的做法,在不知道回傳類型的情況下,不清楚正在組態哪個物件。巢狀結構越深,就越令人困惑。即使是經驗豐富的使用者也會認為他們的組態正在做一件事,但實際上,它正在做另一件事。

  • 一致性。許多程式碼庫在兩種樣式之間切換,導致不一致,使得理解組態變得困難,並且經常導致組態錯誤。

Lambda DSL 組態提示

在比較上面的兩個範例時,您會注意到一些主要差異

  • 在 Lambda DSL 中,無需使用 .and() 方法串聯組態選項。在呼叫 lambda 方法後,HttpSecurity 實例會自動回傳以進行進一步組態。

  • Customizer.withDefaults() 使用 Spring Security 提供的預設值啟用安全性功能。這是 lambda 運算式 it → {} 的捷徑。

WebFlux Security

您也可以使用類似的方式使用 lambda 組態 WebFlux 安全性。以下是使用 lambda 的範例組態。

使用 lambda 的 WebFlux 組態
@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();
    }

}

Lambda DSL 的目標

建立 Lambda DSL 是為了達成以下目標

  • 自動縮排使組態更易於閱讀。

  • 無需使用 .and() 串聯組態選項

  • Spring Security DSL 的組態樣式與其他 Spring DSL(例如 Spring Integration 和 Spring Cloud Gateway)相似。

針對自訂 DSL 使用 .with() 而非 .apply()

在 6.2 之前的版本中,如果您有自訂 DSL,您會使用 HttpSecurity#apply(…​) 方法將其套用至 HttpSecurity。但是,從 6.2 版開始,此方法已被棄用,並將在 7.0 中移除,因為一旦移除 .and(),將不再可能使用 .and() 串聯組態(請參閱 github.com/spring-projects/spring-security/issues/13067)。相反地,建議使用新的 .with(…​) 方法。有關如何使用 .with(…​) 的更多資訊,請參閱自訂 DSL 區段