配置迁移

以下步骤与有关如何配置的更改有关HttpSecurity,WebSecurity和相关组件。spring-doc.cadn.net.cn

使用 Lambda DSL

Lambda DSL 自 5.2 版起就存在于 Spring Security 中,它允许使用 lambda 配置 HTTP 安全性。spring-doc.cadn.net.cn

您可能已经在 Spring Security 文档或示例中看到过这种配置样式。 让我们看看 HTTP 安全的 lambda 配置与之前的配置样式相比如何。spring-doc.cadn.net.cn

使用 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 的首选方式,先前的配置样式在需要使用 Lambda DSL 的 Spring Security 7 中无效。 这样做主要有几个原因:spring-doc.cadn.net.cn

  • 在以前的方式中,在不知道返回类型是什么的情况下,不清楚配置了哪个对象。 嵌套越深,就越混乱。 即使是有经验的用户也会认为他们的配置在做一件事,而实际上,它正在做其他事情。spring-doc.cadn.net.cn

  • 一致性。 许多代码库在两种样式之间切换,这导致了不一致,使理解配置变得困难,并且经常导致配置错误。spring-doc.cadn.net.cn

Lambda DSL 配置提示

比较上述两个示例时,您会注意到一些关键差异:spring-doc.cadn.net.cn

  • 在 Lambda DSL 中,无需使用.and()方法。 这HttpSecurity实例在调用 Lambda 方法后自动返回以进行进一步配置。spring-doc.cadn.net.cn

  • Customizer.withDefaults()使用 Spring Security 提供的默认值启用安全功能。 这是 lambda 表达式的快捷方式it → {}.spring-doc.cadn.net.cn

WebFlux 安全

您也可以以类似的方式使用 lambda 配置 WebFlux 安全性。 下面是使用 lambda 的示例配置。spring-doc.cadn.net.cn

使用 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 是为了实现以下目标:spring-doc.cadn.net.cn

.with()而不是.apply()用于自定义 DSL

在 6.2 之前的版本中,如果你有一个自定义 DSL,你可以将其应用于HttpSecurity使用HttpSecurity#apply(…​)方法。 但是,从版本 6.2 开始,此方法已被弃用,并将在 7.0 中删除,因为它将不再可能使用.and()一次.and()被删除(参见 github.com/spring-projects/spring-security/issues/13067)。 相反,建议使用新的.with(…​)方法。 有关如何使用的更多信息.with(…​)请参阅自定义 DSL 部分spring-doc.cadn.net.cn

dispatcherTypeMatchers而不是shouldFilterAllDispatcherTypes

如果您允许 ERROR 分派,则可以使用shouldFilterAllDispatcherTypes(false)auhorizeHttpRequestsDSL:spring-doc.cadn.net.cn

http
    .authorizeHttpRequests((authorize) -> authorize
        .shouldFilterAllDispatcherTypes(false)
        // ...
    )
http {
    authorizeHttpRequests {
        shouldFilterAllDispatcherTypes = false
        // ...
    }
}

为了准备 7,将其更改为dispatcherTypeMatchers:spring-doc.cadn.net.cn

http
    .authorizHttpRequests((authorize) -> authorize
        .dispatcherTypeMatchers(DispatcherType.ERROR).permitAll()
        // ...
    )
http {
    authorizeHttpRequests {
        authorize(new DispatcherTypeRequestMatcher(DispatcherType.ERROR), permitAll())
    }
}