Bảo mật ứng dụng Spring Boot với Spring Security (Cơ bản)

Đăng ngày: 10-10-2025 18:16
Spring BootSpring SecurityBảo mật ứng dụngSecurityFilterChainformLoginĐăng kýĐăng nhậpĐăng xuất

Chào mừng bạn đến với bài viết thứ 9 trong loạt bài về Spring và Spring Boot! Hôm nay, chúng ta sẽ cùng nhau khám phá một khía cạnh vô cùng quan trọng: bảo mật ứng dụng. Spring Security là một framework mạnh mẽ giúp chúng ta dễ dàng kiểm soát truy cập và bảo vệ ứng dụng khỏi các mối đe dọa.

Trong bài viết này, chúng ta sẽ tập trung vào những kiến thức cơ bản nhất để xây dựng một hệ thống bảo mật đơn giản nhưng hiệu quả. Chúng ta sẽ tìm hiểu cách thêm dependency Spring Security vào dự án. Sau đó cấu hình SecurityFilterChain để định nghĩa các quy tắc bảo mật. Cuối cùng, chúng ta sẽ xây dựng luồng đăng ký, đăng nhập bằng form (formLogin) và đăng xuất.

1. Thêm Dependency Spring Security

Bước đầu tiên, chúng ta cần thêm Spring Security vào dự án Spring Boot của mình. Điều này có thể được thực hiện dễ dàng thông qua Maven hoặc Gradle.

Maven:


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle:


implementation 'org.springframework.boot:spring-boot-starter-security'

Sau khi thêm dependency, Spring Boot sẽ tự động cấu hình Spring Security với các thiết lập mặc định. Điều này có nghĩa là tất cả các endpoint trong ứng dụng của bạn sẽ được bảo vệ và yêu cầu xác thực.

2. Cấu hình SecurityFilterChain

SecurityFilterChain là trái tim của Spring Security. Nó định nghĩa chuỗi các bộ lọc (filters) được áp dụng cho mỗi yêu cầu HTTP. Chúng ta có thể tùy chỉnh SecurityFilterChain để xác định các quy tắc bảo mật riêng cho ứng dụng của mình.

Để cấu hình SecurityFilterChain, chúng ta cần tạo một bean có kiểu `SecurityFilterChain`. Thông thường, chúng ta sẽ sử dụng `@Configuration` và `@Bean` để khai báo bean này.


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .permitAll()
            )
            .logout(logout -> logout.permitAll());
        return http.build();
    }
}

Trong ví dụ trên, chúng ta đã cấu hình SecurityFilterChain để cho phép truy cập không cần xác thực vào các endpoint bắt đầu bằng `/public/`. Tất cả các endpoint khác đều yêu cầu xác thực. Chúng ta cũng đã cấu hình formLogin để sử dụng trang `/login` làm trang đăng nhập.

Giải thích chi tiết:

  • `authorizeHttpRequests()`: Cấu hình các quy tắc ủy quyền (authorization).
  • `requestMatchers("/public/**").permitAll()`: Cho phép truy cập không cần xác thực vào các endpoint bắt đầu bằng `/public/`. Ví dụ: `/public/images/`, `/public/css/`.
  • `anyRequest().authenticated()`: Yêu cầu xác thực cho tất cả các endpoint còn lại.
  • `formLogin()`: Cấu hình form login.
  • `loginPage("/login")`: Chỉ định trang `/login` làm trang đăng nhập.
  • `permitAll()`: Cho phép tất cả mọi người truy cập trang đăng nhập.
  • `logout()`: Cấu hình logout.
  • `permitAll()`: Cho phép tất cả mọi người truy cập trang logout.

3. Xây dựng luồng đăng ký, đăng nhập và đăng xuất

Để hoàn thiện hệ thống bảo mật, chúng ta cần xây dựng luồng đăng ký, đăng nhập và đăng xuất.

Đăng ký

Đầu tiên, chúng ta cần một form đăng ký để người dùng có thể tạo tài khoản mới. Form này sẽ bao gồm các trường như tên người dùng, mật khẩu và email. Khi người dùng gửi form đăng ký, chúng ta sẽ lưu thông tin người dùng vào cơ sở dữ liệu.

Quan trọng nhất là, chúng ta cần mã hóa mật khẩu trước khi lưu vào cơ sở dữ liệu. Spring Security cung cấp `PasswordEncoder` để giúp chúng ta thực hiện việc này.


import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class AppConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Sau đó, bạn có thể tiêm `PasswordEncoder` vào service của bạn và sử dụng nó để mã hóa mật khẩu.


@Service
public class UserService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    public void registerUser(User user) {
        String encodedPassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);
        // Save user to database
    }
}

Đăng nhập

Chúng ta đã cấu hình formLogin trong SecurityFilterChain. Spring Security sẽ tự động xử lý việc đăng nhập khi người dùng gửi form đăng nhập đến trang `/login`. Chúng ta chỉ cần tạo một trang `/login` đơn giản để hiển thị form đăng nhập.

Ví dụ:


<form action="/login" method="post">
  <label for="username">Tên đăng nhập:</label><br>
  <input type="text" id="username" name="username"><br><br>
  <label for="password">Mật khẩu:</label><br>
  <input type="password" id="password" name="password"><br><br>
  <input type="submit" value="Đăng nhập">
</form>

Đăng xuất

Tương tự như đăng nhập, Spring Security cũng tự động xử lý việc đăng xuất. Chúng ta chỉ cần cung cấp một liên kết đăng xuất để người dùng có thể đăng xuất khỏi ứng dụng.

Ví dụ:


<form action="/logout" method="post">
  <input type="submit" value="Đăng xuất">
</form>

Khi người dùng nhấp vào liên kết đăng xuất, Spring Security sẽ xóa session của người dùng và chuyển hướng họ đến trang đăng nhập.

Kết luận

Trong bài viết này, chúng ta đã tìm hiểu những kiến thức cơ bản về Spring Security. Chúng ta đã học cách thêm dependency Spring Security, cấu hình SecurityFilterChain và xây dựng luồng đăng ký, đăng nhập và đăng xuất. Đây chỉ là bước khởi đầu, Spring Security còn rất nhiều tính năng mạnh mẽ khác để khám phá. Hãy tiếp tục tìm hiểu và áp dụng Spring Security để bảo vệ ứng dụng của bạn một cách toàn diện. Đừng ngần ngại thử nghiệm và tìm hiểu sâu hơn để làm chủ framework bảo mật mạnh mẽ này!

0 Bình luận