配置迁移
以下步骤涉及如何配置 HttpSecurity
、WebSecurity
及相关组件的变化。
使用 Lambda DSL
Lambda DSL 自 Spring Security 5.2 版本起就已存在,它允许使用 lambda 表达式来配置 HTTP 安全。
您可能在 Spring Security 文档或示例中见过这种配置风格。让我们来看看 HTTP 安全的 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();
}
}
@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 安全
您也可以以类似方式使用 lambda 配置 WebFlux 安全。以下是使用 lambda 的配置示例。
@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();
}
}
自定义 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 部分。