Chào các bạn, đây là bài viết đầu tiên trong loạt bài viết về Spring Security. Nếu các bạn đang muốn tìm hiểu về các kiến trúc, thành phần, và mối quan hệ giữa chúng trong Spring Security, thì đây sẽ là loạt bài viết phù hợp.
Trong bài viết này giới thiệu về Spring Security, xây dựng dự án đầu tiên. Tiếp theo xem cách các thành phần của nó hoạt động và tương tác với nhau như thế nào.
Giới thiệu Spring Security?
Spring security là một framework cung cấp các giải pháp bảo mật cho ứng dụng Java xây dựng trên Spring Framework. Đây là một framework rất linh hoạt, dễ dàng mở rộng, dễ tích hợp, dễ tùy chỉnh.
Các tính năng chính của Spring security
- Xác thực (Authentication): Hỗ trợ đang dạng các phương pháp xác thực như: Tài khoản mật khẩu, OAuth2, OpenID Connect, JWT (Json web token), LDAP. Và có thể dễ dàng tùy chỉnh logic xác thực phù hợp theo yêu cầu ứng dụng.
- Phân quyền (Authorization): Xác định, giới hạn người dùng truy cập vào tài nguyên ứng dựng dựa vào
vai trò (Roles)
,quyền (permission)
. Cấu hình phân quyền dựa trên URL, các phương thức HTTP (GET, POST, PUT, DELETE), hoặc các method trong ứng dụng qua Annotation. - Bảo vệ chống lại các loại tấn công phổ biến
- CSRF (Cross-site request forgery): Bảo vệ chống lại các yêu cầu giả mạo từ trình duyệt
- XSS (Cross-site scripting): Ngăn chặn việc tiêm mã độc vào ứng dụng
- Session fixation: Ngăn chặn việc khai thác phiên làm việc
Dự án đầu tiên với Spring Security
Hãy tạo dự án đầu tiên với bằng Spring Boot và sử dựng Spring security. Đây là một ứng dụng web cơ bản, thò ra một REST endpoint.
Hai dependency cần thiết:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Thêm một REST Controller có tên là HelloController
với phương thức GET và REST endpoint tương ứng là /hello
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHi(){
return "Hello World";
}
}
Annotation @RestController
đăng ký là bean trong container và thông báo với Spring rằng hãy sử dụng nó là một web controller. Cũng như định nghĩa giá trị trả về nằm trong body của HTTP response. @GetMapping
annotation ánh xạ đường dẫn /hello
đến phương thức triển sayHi()
.
Sau khi chạy ứng dụng, console sẽ hiển thị ra một dòng như sau:
Using generated security password: fdcb1552-96bd-4f65-bf79-a6428c57c2ae
Đây là một khẩu sẽ dùng để đăng nhập vào ứng dụng, nó được tạo mới mỗi khi chạy ứng dụng
Truy cập vào đường dẫn http://localhost:8888/hello
bằng trình duyệt, bạn sẽ được chuyển hướng sang màn hình đăng nhập giống như sau
Nhập user là user, và password được in ra trong console, sau đó login. Sau khi đăng nhập thành công, màn hình hiển thị Hello worlds.
Hoặc các bạn có thể gọi endpoint bằng CMD như sau, mở CMD và gõ dòng lệnh
curl -u user:fdcb1552-96bd-4f65-bf79-a6428c57c2ae localhost:8888/hello
Kết quả trả về là:
Hello worlds!
Ứng dụng đầu tiên đã hoạt động, ít nhất ta đã biết được ứng dụng sẽ như nào gì khi chỉ thêm dependency vào project. Trong phần tiếp theo sẽ xem Spring Boot cấu hình những gì về mặt Spring Security, và sau đó xem cách để tùy chỉnh lại các cấu hình này.
Khung xương triển khai Authentication
Trong phần này, sẽ bàn luận về kiến trúc tổng quan tham gia quá trình Authentication và Authorization. Bạn cần nắm qua các thành phần trong kiến trúc để có thể tự tùy chỉnh theo yêu cầu. Trong loạt bài viết này, mình sẽ nói về Authentication trước rồi sau đó là Authorization.
Ở phần trước, bạn đã thấy logic được thực hiện cho việc xác thực, có user mặc định, mật khẩu được làm mới mỗi khi khởi động ứng dụng. Vậy những đoạn code thực hiện logic đó ở đâu ra? Nó nằm trong các thành phần được Spring Boot thiết lập dựa vào dependency bạn đã thêm vào.
Đây là các thành phần chính tham gia vào quá trình xác thực cho Spring Security và mối quan hệ giữa chúng. Đây cũng là khung xương để triển khai xác thực với Spring Security.
Trong ví dụ ở phần trước, các thành phần này đã triển khai một cấu hình mặc định nên đó là lý do tại sao ta không code gì mà ứng dụng lại hoạt động như thế.
Chi tiết hơn về hình bên trên:
Authentication filter
giao các yêu cầu xác thực cho thằng Authentication Manager để xử lý, và cấu hìnhSecurity context
.Authentication manager
giao cho thằngAuthentication provider
xử lý quá trình xác thựcAuthentication provider
triển khai logic xác thực. Nó sử dụng User details service để tìm user và Password encoder để xác thực mật khẩu.User details service
triển khai việc quản lý user.Password encoder
triển khai việc quản lý mật khẩu.Security context
lưu thông tin xác thực sau khi quá trình xác thực kết thúc.
Tổng kết
Tóm tắt một số điều trong bài viết này như sau:
- Spring boot cung cấp một số cấu hình mặc định khi bạn thêm Spring Security Dependency vào ứng dụng.
- Bạn đã thấy được khung xương sống để triển khai quá trình xác thực sử dụng Spring security
Trong bài viết tiếp theo sẽ thảo luận về triển khai các thành phần mặc định này.