Spring Security 6: เลิกใช้ WebSecurityConfigurerAdapter แล้วใช้อะไรแทน? (ฉบับอัปเดต Spring Boot 3)
ใครที่เพิ่งอัปเกรดโปรเจกต์เป็น Spring Boot 3.x หรือเริ่มโปรเจกต์ใหม่ น่าจะเจอปัญหาเดียวกันคือ Class ยอดฮิตอย่าง WebSecurityConfigurerAdapter ถูกขีดฆ่า (Deprecated) หรือหายไปจาก Library เลย
นี่ไม่ใช่ Bug แต่เป็น "Major Change" ของ Spring Security 5.7 ขึ้นไป (และบังคับใช้เต็มตัวใน Spring Security 6) ที่เปลี่ยนกระบวนทัศน์การเขียน Config จากเดิมที่ใช้การ Inheritance (สืบทอด Class) มาเป็นการใช้ Component-based (ประกาศ Bean) แทน
บทความนี้จะพาคุณเปลี่ยน Code เก่าให้เป็น Code ใหม่ภายใน 5 นาทีครับ
1. เปลี่ยนโครงสร้าง: จาก extends มาเป็น @Bean
แบบเก่า (The Old Way)
เมื่อก่อนเราต้องสร้าง Class มา extends WebSecurityConfigurerAdapter แล้ว override method configure
// ❌ เลิกใช้แบบนี้
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
แบบใหม่ (The New Way)
ใน Spring Security 6 เราไม่ต้อง extends อะไรแล้วครับ แค่ประกาศ @Bean ที่คืนค่า SecurityFilterChain ก็จบเลย
// ✅ แบบใหม่ (Spring Boot 3 / Security 6)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// เขียน Config ตรงนี้ (เดี๋ยวมาดู syntax ใหม่กันข้างล่าง)
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
return http.build();
}
}
2. เปลี่ยน Syntax: Lambda DSL คือมาตรฐานใหม่
สังเกตไหมครับว่า Code แบบใหม่ไม่มีการใช้ .and() แล้ว?
Spring Security 6 ผลักดันให้เขียนแบบ Lambda DSL เพื่อให้อ่านง่ายขึ้นและลดความสับสนของการซ้อน method
- CSRF:เก่า:
.csrf().disable()ใหม่:.csrf(csrf -> csrf.disable())- เก่า:
.csrf().disable() - ใหม่:
.csrf(csrf -> csrf.disable())
- เก่า:
- Permissions:เก่า:
.authorizeRequests()ใหม่:.authorizeHttpRequests(auth -> ...)(เปลี่ยนชื่อ Method ด้วย!)- เก่า:
.authorizeRequests() - ใหม่:
.authorizeHttpRequests(auth -> ...)(เปลี่ยนชื่อ Method ด้วย!)
- เก่า:
- Matchers:เก่า:
.antMatchers("/api/**")ใหม่:.requestMatchers("/api/**")(สำคัญ: antMatchers หายไปแล้ว)- เก่า:
.antMatchers("/api/**") - ใหม่:
.requestMatchers("/api/**")(สำคัญ: antMatchers หายไปแล้ว)
- เก่า:
3. จัดการ WebSecurity (Ignoring Static Resources)
ถ้าเมื่อก่อนคุณเคย override configure(WebSecurity web) เพื่อให้ Security ข้ามการตรวจเช็คไฟล์พวก CSS/JS/Images
แบบเก่า
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/css/**", "/js/**");
}
แบบใหม่
ใช้ Bean WebSecurityCustomizer แทนครับ
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/css/**", "/js/**");
}
4. จัดการ UserDetailsService (Authentication)
ถ้าคุณเคย override configure(AuthenticationManagerBuilder auth) เพื่อทำ In-Memory User หรือต่อ Database
แบบเก่า
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("pass").roles("ADMIN");
}
แบบใหม่
ให้ประกาศ UserDetailsService เป็น Bean แยกออกมาเลย Spring จะหยิบไปใช้เองอัตโนมัติ
@Bean
public UserDetailsService userDetailsService() {
UserDetails admin = User.withUsername("admin")
.password("{noop}pass") // {noop} คือไม่ encrypt (ใช้เฉพาะ test)
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(admin);
}
สรุป Checklist การย้ายมา Spring Security 6
- ลบ
extends WebSecurityConfigurerAdapterทิ้ง - สร้าง
@BeanSecurityFilterChain - เปลี่ยน
authorizeRequests()->authorizeHttpRequests() - เปลี่ยน
antMatchers()->requestMatchers() - เขียน Config ในรูปแบบ Lambda DSL (
.func(c -> c...))
ถึงจะดูยุ่งยากในช่วงแรก แต่แบบใหม่นี้ทำให้เราสามารถมี Security Config หลายตัวในโปรเจกต์เดียวกันได้ง่ายขึ้น และลดปัญหาการแย่งกัน Override method ที่เคยเจอในแบบเก่าครับ
No responses yet. Be the first to respond.