3. Authentication Flow
Hãy đi sâu vào Authentication Flow trong Spring Security. Tôi sẽ giải thích về AuthenticationManager
và AuthenticationProvider
, cùng với quy trình xác thực từ khi nhận request đến khi trả về response.
1. AuthenticationManager và AuthenticationProvider
a. AuthenticationManager
Định nghĩa:
AuthenticationManager
là một giao diện trong Spring Security, chịu trách nhiệm xử lý quá trình xác thực (authentication). Nó nhận một đối tượngAuthentication
chưa xác thực (unauthenticated) và trả về một đối tượngAuthentication
đã xác thực (authenticated) nếu thành công, hoặc ném ngoại lệ nếu thất bại.
Vai trò:
Là "người điều phối" chính trong luồng xác thực, quyết định cách xác minh thông tin đăng nhập (credentials) của người dùng.
Thường được triển khai bởi lớp
ProviderManager
, một implementation mặc định của Spring Security.
Cách hoạt động:
ProviderManager
chứa một danh sách cácAuthenticationProvider
. Nó thử từng provider theo thứ tự cho đến khi một provider xác thực thành công hoặc hết danh sách.
b. AuthenticationProvider
Định nghĩa:
AuthenticationProvider
là giao diện xác định logic xác thực cụ thể. Mỗi provider hỗ trợ một loại xác thực (ví dụ: username/password, JWT, LDAP).
Vai trò:
Thực hiện việc kiểm tra thông tin đăng nhập (credentials) và trả về đối tượng
Authentication
đã xác thực.Cho phép tùy chỉnh logic xác thực theo nhu cầu.
Ví dụ:
DaoAuthenticationProvider
: Một provider mặc định, dùngUserDetailsService
để lấy thông tin người dùng từ cơ sở dữ liệu vàPasswordEncoder
để so sánh mật khẩu.
Cấu trúc cơ bản:
Mối quan hệ giữa AuthenticationManager và AuthenticationProvider
AuthenticationManager
(thường làProviderManager
) ủy thác công việc xác thực cho một hoặc nhiềuAuthenticationProvider
.Nếu có nhiều provider,
ProviderManager
sẽ duyệt qua danh sách để tìm provider phù hợp (dựa trên phương thứcsupports()
).
2. Quy trình xác thực từ request đến response
Dưới đây là luồng chi tiết của quá trình xác thực trong Spring Security, từ khi nhận request đến khi trả về response, lấy ví dụ với form login (username/password):
Bước 1: Request đến và Filter Chain bắt đầu
Một request (ví dụ: POST
/login
với username và password) được gửi đến server.FilterChainProxy
(Security Filter Chain) bắt đầu xử lý request, và filter liên quan đến xác thực (nhưUsernamePasswordAuthenticationFilter
) được kích hoạt.
Bước 2: UsernamePasswordAuthenticationFilter xử lý
Vai trò: Filter này nhận request POST từ form login (mặc định
/login
).Hoạt động:
Trích xuất
username
vàpassword
từ request.Tạo đối tượng
UsernamePasswordAuthenticationToken
(unauthenticated):Gửi
authRequest
đếnAuthenticationManager
để xác thực:
Bước 3: AuthenticationManager xử lý
ProviderManager
nhậnauthRequest
và duyệt qua danh sáchAuthenticationProvider
.Giả sử dùng
DaoAuthenticationProvider
:Kiểm tra loại xác thực:
supports()
xác nhận provider này hỗ trợUsernamePasswordAuthenticationToken
.
Tải thông tin người dùng:
Gọi
UserDetailsService.loadUserByUsername(username)
để lấyUserDetails
(bao gồm username, password đã mã hóa, roles).
So sánh mật khẩu:
Dùng
PasswordEncoder
để kiểm tra mật khẩu nhập vào với mật khẩu lưu trữ.Nếu khớp, tạo
Authentication
đã xác thực:Nếu không khớp, ném
BadCredentialsException
.
Bước 4: Lưu Authentication vào SecurityContext
Sau khi xác thực thành công,
UsernamePasswordAuthenticationFilter
:Lưu
authResult
vàoSecurityContextHolder
:Gọi
successHandler
(mặc định chuyển hướng đến trang chính hoặc URL trước đó).
Bước 5: SecurityContextPersistenceFilter lưu trữ
Ở cuối Filter Chain,
SecurityContextPersistenceFilter
lưuSecurityContext
vàoHttpSession
(dưới keySPRING_SECURITY_CONTEXT
) để dùng cho các request sau.
Bước 6: Response trả về
Nếu xác thực thành công:
Người dùng được chuyển hướng (redirect) hoặc nhận response (trong trường hợp API).
Nếu thất bại:
ExceptionTranslationFilter
bắt ngoại lệ (nhưAuthenticationException
) và gọifailureHandler
(mặc định chuyển hướng về form login với thông báo lỗi).
Luồng tổng quát (hình dung):
Ví dụ cụ thể: Cấu hình Authentication Flow
Giải thích:
AuthenticationManager
được cấu hình vớiDaoAuthenticationProvider
(tự động).UserDetailsService
cung cấp thông tin người dùng.UsernamePasswordAuthenticationFilter
xử lý form login tại/login
.
Tùy chỉnh Authentication Flow
Custom AuthenticationProvider:
Đăng ký:
Tóm tắt
AuthenticationManager: Điều phối xác thực, giao việc cho
AuthenticationProvider
.AuthenticationProvider: Thực hiện logic xác thực cụ thể (ví dụ: kiểm tra username/password).
Quy trình:
Filter nhận request → Tạo
Authentication
chưa xác thực.AuthenticationManager
→AuthenticationProvider
xác thực.Lưu kết quả vào
SecurityContext
→ Trả về response.
Bạn muốn tôi đi sâu hơn vào phần nào (ví dụ: custom provider chi tiết, debug luồng xác thực), hay tiếp tục với phần khác trong roadmap?
Last updated