虽然 Spring Security7.0 尚未确定发布日期,但是我们还是需要提前做一些准备工作,因为在已知的信息中,在 Spring Security7.0 中会有一大批大家熟悉的 API 被移除,这些 API 在 Spring Security6 中已经处于废弃状态,但是还能用,但是到了 Spring Security7.0,这些就被移除了,所以我们还是有必要来看看 Spring Security7.0 中的一些比较典型的变化。
1. lambda 配置 Lambda DSL 自 Spring Security 5.2 版本以来就存在,它允许使用 lambda 表达式配置 HTTP 安全性。
我们来看看使用 lambda 配置 HTTP 安全性与之前的配置风格相比有何差别:
使用 lambda 的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @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 的等效配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @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 Security6 中旧版写法被废弃了,在 Spring Security7 中旧版写法将被移除,也就是未来必须使用 Lambda DSL 来配置。这样做的主要原因有:
之前的方式在不知道返回类型的情况下,不清楚哪个对象正在被配置。
嵌套越深,维护越不方便。
许多代码库在这两种风格之间切换,这导致了不一致性,使得理解配置变得困难,并经常导致配置错误。
2. Lambda DSL 配置技巧 当比较上述两个示例时,我们会注意到一些关键差异:
在 Lambda DSL 中,不需要使用 .and()
方法来链式配置选项。
在 lambda 方法调用后,HttpSecurity
实例会自动返回以进行进一步配置。
Customizer.withDefaults()
使用 Spring Security 提供的默认值启用安全特性。
3. WebFlux 配置 我们也可以使用 lambda 以类似的方式配置 WebFlux 项目。以下是使用 lambda 的示例配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @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(); } }
4. Lambda DSL 的优势
自动缩进使配置更易读。
不需要使用 .and()
来链式配置选项。
Spring Security DSL 的配置风格与其他 Spring DSL(如 Spring Integration 和 Spring Cloud Gateway)相似,可以更快的上手。