Cách thức hoạt động của SSO trong EzyLogin
Back to ezyloginSSO, viết tắt của Single Sign-On, là cơ chế cho phép người dùng đăng nhập một lần tại một hệ thống định danh trung tâm, sau đó truy cập nhiều ứng dụng khác nhau mà không phải nhập lại tài khoản mật khẩu ở từng ứng dụng. Trong EzyLogin, SSO được triển khai theo hướng EzyLogin đóng vai trò máy chủ định danh cho người dùng: xác thực phiên đăng nhập, kiểm tra client, phát hành authorization code, cấp token, cung cấp thông tin người dùng và quản lý vòng đời token.
Kiến Trúc Tổng Quát
EzyLogin hoạt động như một SSO issuer cho các ứng dụng client đã đăng ký. Mỗi client có
client_id, client_secret, danh sách redirect_uri, scope được phép dùng, trạng thái kích hoạt và chính sách consent.
flowchart LR
NguoiDung["Người dùng"] --> Client["Ứng dụng client"]
Client --> EzyLogin["EzyLogin SSO"]
EzyLogin --> PhienDangNhap["Phiên đăng nhập người dùng"]
EzyLogin --> CauHinhClient["Cấu hình client"]
EzyLogin --> KhoToken["Kho token và mã xác thực"]
EzyLogin --> KhoaKy["Khóa ký JWT và JWKS"]
CauHinhClient --> RedirectUri["Redirect URI hợp lệ"]
CauHinhClient --> Scope["Scope được cấp"]
KhoToken --> AuthCode["Authorization code"]
KhoToken --> AccessToken["Access token"]
KhoToken --> RefreshToken["Refresh token"]
EzyLogin cũng công bố OpenID Connect discovery để client biết các endpoint cần dùng, gồm authorization endpoint, token endpoint, userinfo endpoint, JWKS endpoint, introspection endpoint, revocation endpoint, PAR endpoint và logout endpoint.
Luồng Đăng Nhập SSO
Luồng đăng nhập bắt đầu khi client điều hướng người dùng đến authorization endpoint của EzyLogin. Request thường chứa
client_id, redirect_uri, response_type, scope, state, nonce hoặc request_uri.Nếu người dùng chưa đăng nhập, EzyLogin yêu cầu đăng nhập trước. Khi người dùng đã có session hợp lệ, EzyLogin kiểm tra request, client, redirect URI và scope. Nếu client yêu cầu consent, người dùng được đưa đến màn hình phê duyệt. Nếu không cần consent, hệ thống tạo hoặc lấy lại authorization code và redirect về client.
sequenceDiagram
participant NguoiDung as Người dùng
participant Client as Ứng dụng client
participant SSO as EzyLogin SSO
participant Kho as Kho dữ liệu SSO
NguoiDung->>Client: Mở chức năng đăng nhập
Client->>SSO: Chuyển hướng tới authorization endpoint
SSO->>SSO: Kiểm tra phiên đăng nhập
SSO->>Kho: Kiểm tra client, redirect URI, scope
alt Cần người dùng đồng ý
SSO->>NguoiDung: Hiển thị màn hình consent
NguoiDung->>SSO: Đồng ý cấp quyền
end
SSO->>Kho: Tạo hoặc lấy authorization code
SSO->>Client: Redirect về redirect URI kèm code và state
state được trả lại cho client để client đối chiếu request ban đầu. nonce nếu có sẽ được lưu cùng authorization code và đưa vào id_token ở bước cấp token.Consent
Consent là bước EzyLogin yêu cầu người dùng xác nhận việc cho phép client sử dụng thông tin đăng nhập. Việc có hiển thị consent hay không phụ thuộc vào cấu hình approval prompt của client và giá trị
prompt trong request.Khi người dùng approve, EzyLogin kiểm tra lại client, redirect URI, response type và scope, sau đó tạo authorization code. Các hành động tạo authorization code được ghi audit log với thông tin như client, IP, user agent, trạng thái và thời điểm xử lý.
Đổi Code Lấy Token
Sau khi nhận authorization code, client gọi token endpoint để đổi code lấy token. Ở bước này, client phải gửi đúng
client_id, client_secret, redirect_uri, grant_type và code.
sequenceDiagram
participant Client as Ứng dụng client
participant SSO as EzyLogin SSO
participant Kho as Kho token
participant JWT as Dịch vụ ký JWT
Client->>SSO: Gửi code, client_id, client_secret, redirect_uri
SSO->>SSO: Kiểm tra client secret và redirect URI
SSO->>Kho: Kiểm tra authorization code
SSO->>Kho: Tạo hoặc lấy refresh token
SSO->>Kho: Tạo hoặc cập nhật access token
SSO->>JWT: Ký id token bằng RS256
SSO->>Client: Trả access token, refresh token, id token
Token response gồm
token_type, access_token, refresh_token, expires_in, scope, id_token và id_token_expires_in.id_token là JWT được ký bằng RS256. Payload chứa các claim chính như iss, sub, aud, iat, exp, nonce và sid. Trong đó sid đại diện cho phiên refresh token, được dùng trong luồng logout.Refresh Token
Khi access token hết hạn, client có thể dùng refresh token để xin access token mới. EzyLogin kiểm tra refresh token có tồn tại, còn được kích hoạt, chưa hết hạn và thuộc đúng client hay không.
flowchart TD
BatDau["Client gửi refresh token"] --> KiemTra["Kiểm tra client và refresh token"]
KiemTra --> HopLe{"Refresh token hợp lệ?"}
HopLe -- "Không" --> Loi["Trả lỗi token không hợp lệ hoặc hết hạn"]
HopLe -- "Có" --> LayUser["Lấy SSO user tương ứng"]
LayUser --> CapToken["Tạo hoặc cập nhật access token"]
CapToken --> TraVe["Trả token response mới"]
Cơ chế này giúp client duy trì phiên mà không cần bắt người dùng đăng nhập lại quá thường xuyên.
UserInfo
Sau khi có access token, client gọi userinfo endpoint với header
Authorization: Bearer <access_token>. EzyLogin dùng access token để tìm SSO user, ánh xạ sang user thật trong hệ thống và trả về thông tin hồ sơ.Thông tin trả về gồm
sub, email, email_verified, name và picture. Trong EzyLogin, sub là định danh SSO user theo quan hệ user-client, không đơn giản là user id nội bộ.Introspection Và Revocation
Introspection cho phép client kiểm tra trạng thái token. Client phải xác thực bằng
client_id và client_secret. Token chỉ được introspect nếu thuộc đúng client đang gọi.Revocation cho phép client thu hồi access token hoặc refresh token. Khi revoke, EzyLogin cập nhật trạng thái token và ghi audit log.
flowchart LR
Client["Ứng dụng client"] --> XacThuc["Xác thực client_id và client_secret"]
XacThuc --> TimToken["Tìm token theo token_type_hint"]
TimToken --> DungClient{"Token thuộc đúng client?"}
DungClient -- "Không" --> KhongTimThay["Trả lỗi không tìm thấy token"]
DungClient -- "Có" --> XuLy["Introspect hoặc revoke"]
XuLy --> Audit["Ghi audit log nếu revoke"]
Token được xem là active khi chưa hết hạn và đang ở trạng thái kích hoạt.
Logout SSO
Luồng logout nhận
id_token_hint, post_logout_redirect_uri và state. EzyLogin xác thực id_token_hint, lấy client id từ audience và lấy session id từ claim sid. Sau đó hệ thống đánh dấu refresh token là logged out và đánh dấu các access token còn hiệu lực liên quan đến refresh token đó là logged out.
sequenceDiagram
participant Client as Ứng dụng client
participant SSO as EzyLogin SSO
participant Kho as Kho token
Client->>SSO: Gửi id_token_hint và post_logout_redirect_uri
SSO->>SSO: Xác thực id token
SSO->>Kho: Tìm phiên refresh token theo sid
SSO->>Kho: Đánh dấu refresh token là đã đăng xuất
SSO->>Kho: Đánh dấu access token liên quan là đã đăng xuất
SSO->>Client: Redirect về post logout URI kèm state
Nếu
post_logout_redirect_uri không được gửi, EzyLogin chuyển người dùng về home URI mặc định. Nếu có gửi, URI này phải thuộc danh sách redirect URI hợp lệ của client.Pushed Authorization Request
EzyLogin hỗ trợ Pushed Authorization Request. Thay vì đưa toàn bộ dữ liệu authorization lên URL trình duyệt, client gửi trước request lên PAR endpoint. EzyLogin lưu request tạm thời và trả về
request_uri.Sau đó client đưa người dùng đến authorization endpoint với
request_uri. EzyLogin lấy lại dữ liệu đã lưu, kiểm tra hạn sử dụng và tiếp tục luồng authorize như bình thường.
sequenceDiagram
participant Client as Ứng dụng client
participant SSO as EzyLogin SSO
participant Kho as Kho dữ liệu tạm
Client->>SSO: Gửi pushed authorization request
SSO->>Kho: Lưu request tạm thời
SSO->>Client: Trả request_uri và thời gian hết hạn
Client->>SSO: Chuyển hướng người dùng với request_uri
SSO->>Kho: Lấy lại request đã lưu
SSO->>SSO: Tiếp tục kiểm tra client, scope, redirect URI
Cơ chế này giúp giảm lượng dữ liệu nhạy cảm xuất hiện trực tiếp trên URL trình duyệt.
Bảo Mật Và Kiểm Soát
SSO trong EzyLogin có nhiều lớp kiểm soát:
- client phải tồn tại và đang được kích hoạt,
- client secret được kiểm tra ở các endpoint backend-to-backend,
- redirect URI phải được đăng ký trước,
- scope request không được vượt quá scope client được cấp,
- access token và refresh token có trạng thái riêng,
- token có thời gian hết hạn,
- id token được ký bằng RS256,
- public key được công bố qua JWKS,
- các hành động quan trọng được ghi audit log.
Giới Hạn Cần Lưu Ý
EzyLogin triển khai luồng SSO theo hướng authorization code và refresh token. Discovery metadata mặc định công bố
response_type là code, grant type là authorization_code và refresh_token, scope phổ biến gồm openid, email, profile.Hệ thống không tự động cấp quyền ngoài scope đã đăng ký cho client. Client cũng không thể dùng redirect URI tùy ý nếu URI đó chưa được cấu hình trước.
Kết Luận
SSO trong EzyLogin hoạt động như một lớp định danh trung tâm: người dùng đăng nhập vào EzyLogin, client nhận authorization code, đổi code lấy token, dùng access token để lấy thông tin user, và có thể kiểm tra, thu hồi hoặc logout token khi cần. Thiết kế này giúp nhiều ứng dụng dùng chung một nguồn xác thực, đồng thời vẫn giữ được kiểm soát client, redirect URI, scope, token lifetime và audit log cho từng phiên đăng nhập.