Why Spring Security 7.0 Forces Lambda DSL and How to Migrate Your Configurations
Spring Security 7.0 drops the traditional chain‑style configuration in favor of a new Lambda DSL, offering clearer hierarchy, type safety, and IDE support; the article explains the breaking change, compares old and new syntax, provides migration examples, and shares tips for custom DSLs and WebFlux security.
Spring Security 7.0 will completely remove the traditional chain‑style configuration, requiring developers to migrate to the new Lambda DSL configuration. This is a breaking change that demands code adjustments in all projects using Spring Security.
Lambda DSL Configuration
From Spring Security 5.2 the Lambda DSL was introduced and will become the only supported configuration method in version 7.0. The following example demonstrates this style.
Problems with the Traditional Configuration
The classic approach has several drawbacks:
Using
.and()to chain configuration blocks creates deep nesting and poor readability.
The relationship between configuration blocks is unclear, leading to scope confusion.
IDE code completion and type hints are limited.
Configuration errors are only detected at runtime.
Advantages of Lambda DSL
Compared with the old style, Lambda DSL offers:
Clear hierarchical structure with explicit scopes.
Better type safety; errors are caught at compile time.
Accurate IDE code completion.
Easier reuse and composition of configuration logic.
Simpler code without the need for
.and().
Typical Lambda DSL Configuration
<code>@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/token/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(formLogin ->
formLogin
.loginPage("/login")
.permitAll()
)
.rememberMe(Customizer.withDefaults());
return http.build();
}
}
</code>Traditional Configuration (Removed in 7.0)
<code>@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers("/token/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.rememberMe();
return http.build();
}
}
</code>Why Enforce Lambda DSL?
The Spring Security team mandates Lambda DSL for two main reasons:
Clearer configuration hierarchy – without knowing return types, the old style becomes hard to understand as nesting deepens.
Consistency – mixing two styles leads to inconsistent code and higher risk of errors.
Lambda DSL Usage Tips
When using Lambda DSL, keep in mind:
Do not use
.and(); the HttpSecurity instance is returned automatically after each lambda call.
Default configuration can be abbreviated with
Customizer.withDefaults(), which is a short form of
it -> {}.
WebFlux Security Configuration
WebFlux also supports Lambda DSL:
<code>@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();
}
}
</code>Design Goals of Lambda DSL
Automatic indentation – IDE auto‑indentation improves readability.
Removal of
.and()for a cleaner API.
Unified style – aligns with other Spring DSLs such as Spring Integration and Spring Cloud Gateway.
Custom DSL Changes
Since version 6.2, custom DSLs should replace the deprecated
HttpSecurity#apply(...)with the new
.with(...)method, because
.and()will be removed entirely in 7.0.
How to Create a Custom DSL
Below is a complete example of a custom DSL implementation:
<code>public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> {
private boolean flag;
@Override
public void init(HttpSecurity http) throws Exception {
// Add other configurers here, e.g., disable CSRF
http.csrf().disable();
}
@Override
public void configure(HttpSecurity http) throws Exception {
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
MyFilter myFilter = context.getBean(MyFilter.class);
myFilter.setFlag(flag);
http.addFilterBefore(myFilter, UsernamePasswordAuthenticationFilter.class);
}
public MyCustomDsl flag(boolean value) {
this.flag = value;
return this;
}
public static MyCustomDsl customDsl() {
return new MyCustomDsl();
}
}
</code>Using the Custom DSL
In a configuration class you can apply the custom DSL as follows:
<code>@Configuration
@EnableWebSecurity
public class Config {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.with(MyCustomDsl.customDsl(), dsl -> dsl
.flag(true)
)
// ... other configurations
;
return http.build();
}
}
</code>Key points when building a custom DSL:
Extend
AbstractHttpConfigurerto obtain the necessary base class.
Add additional configurers in the
initmethod.
Implement the actual security logic in the
configuremethod.
Provide a fluent API to keep the configuration style consistent.
Expose a static factory method for creating DSL instances.
Conclusion
Spring Security 7.0’s shift to Lambda DSL brings clearer, more consistent configuration and better compile‑time safety. Teams should start migrating early to ensure a smooth transition to the new version.
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.