Trong bài viết trước, mình đã hướng dẫn các bạn cấu hình Spring Security sử dụng class WebSecurityConfigurerAdapter. Từ Spring Security phiên bản 5.7.0 trở đi, Spring deprecated class này và recommend chúng ta cấu hình Spring Security với một bean của SecurityFilterChain và Spring Security Lambda DSL. Cụ thể như thế nào? Chúng ta sẽ cùng nhau tìm hiểu trong bài viết này các bạn nhé!
Mình sẽ clone project ví dụ trong bài viết trước để compare việc cấu hình giữa 2 solution khác nhau như thế nào!
Nếu bây giờ, các bạn tăng version của Spring Security lên version 5.7.0-M2, các bạn sẽ thấy class WebSecurityConfigurerAdapter bị deprecated như sau:
Bây giờ chúng ta sẽ thay thế nó với SecurityFilterChain và Spring Security Lambda DSL các bạn nhé!
Class chính mà chúng ta sẽ làm việc là SpringSecurityConfiguration, mình sẽ remove hết những code không cần thiết, annotate class này với annotation @EnableWebSecurity như sau:
1 2 3 4 5 6 7 8 |
package com.huongdanjava.springsecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @EnableWebSecurity public class SpringSecurityConfiguration { } |
Bây giờ chúng ta sẽ cấu hình cho phần authorization sử dụng class SecurityFilterChain với class HttpSecurity trước.
Mình sẽ khai báo như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // @formatter:off http .authorizeHttpRequests((authz) -> authz .antMatchers("/").hasRole("USER") .antMatchers("/admin/**").hasRole("ADMIN") ) .formLogin(withDefaults()); // @formatter:on return http.build(); } |
Như các bạn thấy, mình sử dụng một phương thức khác của class HttpSecurity để cấu hình permission access tới các request URLs của ứng dụng, phương thức authorizeHttpRequests(). Có một phương thức overloading khác của phương thức này không có tham số dùng để apply những cấu hình mặc định mà Spring Security cung cấp.
Tham số của phương thức authorizeHttpRequests() trong ví dụ này là interface Customizer được định nghĩa với theo kiểu generic giúp chúng ta có thể cấu hình phần authorization này theo ý của mình.
Interface Customizer là một Functional Interface và do đó, chúng ta có thể sử dụng Java Lambda Expression để viết code cho phương thức này. Spring gọi cách viết này là Lambda DSL. Nói nôm na thì Spring hỗ trợ Lambda DSL để giúp code chúng ta dễ đọc hiểu hơn, chúng ta không cần sử dụng phương thức and() để cấu hình các phần khác nhau của Spring Security nữa.
Type của interface Customizer cho phần authorization này là class AuthorizationManagerRequestMatcherRegistry định nghĩa thông tin các request URL và role nào được phép access.
Phương thức formLogin() cũng hỗ trợ Lambda DSL, cho phép chúng ta cấu hình phần login page, sử dụng mặc định của Spring Security (phương thức withDefaults()) hoặc các bạn cũng có thể customize theo ý của mình. Type của interface Customizer trong trường hợp này là class FormLoginConfigurer.
Cho phần quản lý thông tin user đăng nhập ứng dụng, các bạn có thể khai báo một bean của class InMemoryUserDetailsManager để thêm thông tin user trong memory, như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Bean public UserDetailsManager userDetailsService() { UserDetails user1 = User.withDefaultPasswordEncoder() .username("khanh") .password("123456") .roles("USER") .build(); UserDetails user2 = User.withDefaultPasswordEncoder() .username("thanh") .password("123456") .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(user1, user2); } |
Để ignore security cho các request tới resource của ứng dụng, chúng ta có thể khai báo một bean của class WebSecurityCustomizer với cấu hình ví dụ như sau:
1 2 3 4 |
@Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring().antMatchers("/resources/**"); } |
WebSecurityCustomizer là một Functional Interface với một phương thức là customize(). Tham số của phương thức này là class WebSecurity giúp chúng ta có thể định nghĩa resource mà chúng ta muốn ignore đó các bạn!
Đến đây thì chúng ta đã hoàn thành việc cấu hình Spring Security sử dụng SecurityFilterChain và Lambda DSL rồi.
Chạy lại ví dụ các bạn sẽ thấy mọi thứ đều như chúng ta đã làm trong bài viết Cấu hình Spring Security sử dụng WebSecurityConfigurerAdapter và AbstractSecurityWebApplicationInitializer