Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 27 — Authentication & Federation — SSO, OIDC, SAML

Đã đọc 0/16 mục · còn khoảng 13 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn vừa vào làm ở một công ty công nghệ tại TP.HCM. Ngày đầu tiên, IT gửi cho bạn một danh sách dài: tài khoản email công ty, tài khoản Slack, tài khoản Jira, tài khoản AWS Console, tài khoản Confluence, tài khoản hệ thống chấm công. Sáu hệ thống, sáu mật khẩu khác nhau. Bạn sẽ làm gì? Đa số người sẽ đặt cùng một mật khẩu cho tất cả, hoặc ghi ra một file Excel. Cả hai cách đều là thảm họa an ninh.

Đây chính là bài toán mà Authentication (xác thực) và Federation (liên kết định danh) giải quyết. Trong các bài trước, chúng ta đã nói về IAM — ai được phép làm gì trong một hệ thống cloud. Nhưng IAM giả định rằng hệ thống đã biết bạn là ai. Câu hỏi cốt lõi của bài này là: làm sao một hệ thống biết chắc chắn bạn là bạn, và làm sao để một lần đăng nhập có thể mở cửa cho nhiều hệ thống khác nhau một cách an toàn?

Với vai trò kỹ sư DevOps hoặc Cloud, bạn sẽ liên tục gặp các thuật ngữ SSO, OIDC, SAML khi cấu hình đăng nhập cho AWS, GCP, Azure, khi tích hợp Google Workspace vào ứng dụng nội bộ, hay khi dựng hệ thống đăng nhập cho khách hàng. Hiểu rõ những giao thức này không chỉ giúp bạn cấu hình đúng, mà còn giúp bạn tránh những lỗ hổng bảo mật nghiêm trọng có thể khiến toàn bộ hệ thống bị chiếm quyền. Đây là kiến thức nền tảng mà bất kỳ kỹ sư hạ tầng nào cũng phải nắm chắc.

Khái niệm cốt lõi

Phân biệt Authentication và Authorization

Trước hết phải làm rõ hai khái niệm hay bị nhầm lẫn:

  • Authentication (AuthN — xác thực): trả lời câu hỏi "Bạn là ai?". Khi bạn nhập username và password, khi bạn quét vân tay, khi bạn nhập mã OTP — đó là quá trình chứng minh danh tính.
  • Authorization (AuthZ — phân quyền): trả lời câu hỏi "Bạn được phép làm gì?". Sau khi biết bạn là ai, hệ thống mới quyết định bạn có được xóa file, chỉnh sửa cấu hình hay không.
Bài này tập trung vào Authentication và cách mở rộng nó thành Federation — tức là chia sẻ danh tính giữa nhiều hệ thống. Phần phân quyền chi tiết (policy, role) thuộc về bài IAM.

SSO — Single Sign-On là gì?

Single Sign-On (SSO) nghĩa là một lần đăng nhập, truy cập được nhiều dịch vụ. Thay vì nhớ sáu mật khẩu như ví dụ mở đầu, bạn chỉ đăng nhập một lần vào một nơi trung tâm (gọi là Identity Provider — IdP), và tất cả các ứng dụng khác (gọi là Service Provider — SP hoặc Relying Party) sẽ tin tưởng IdP đó.

Điểm mấu chốt của SSO là sự tin tưởng (trust) giữa các bên. Ứng dụng Jira không tự kiểm tra mật khẩu của bạn. Thay vào đó, nó hỏi IdP (ví dụ Google hoặc Azure AD): "Người này có đúng là nhân viên hợp lệ không?". IdP xác nhận, và Jira tin lời xác nhận đó. Sự tin tưởng này được thiết lập trước bằng cách trao đổi khóa mã hóa và cấu hình.

Lợi ích của SSO rất rõ ràng:

  • Trải nghiệm người dùng tốt hơn: không phải nhớ nhiều mật khẩu.
  • An ninh cao hơn: chỉ cần bảo vệ một điểm đăng nhập trung tâm thật chắc (bật MFA ở đó là đủ bảo vệ tất cả).
  • Quản trị dễ dàng: nhân viên nghỉ việc, chỉ cần vô hiệu hóa tài khoản ở IdP là mất quyền truy cập mọi ứng dụng ngay lập tức. Đây là điều cực kỳ quan trọng — nếu không có SSO, bạn phải nhớ đi xóa tài khoản ở từng hệ thống, và thường sẽ sót.

Federation — liên kết định danh giữa các tổ chức

Federation là mức mở rộng của SSO ra ngoài ranh giới một tổ chức. Ví dụ, công ty A muốn cho nhân viên đăng nhập vào hệ thống của đối tác B mà không cần B tạo tài khoản riêng. B sẽ liên kết (federate) với IdP của A và tin tưởng danh tính do A cung cấp.

Trong thế giới cloud, federation cực kỳ phổ biến: bạn dùng tài khoản Google Workspace của công ty để đăng nhập vào AWS Console. AWS không lưu mật khẩu của bạn — nó liên kết với Google làm IdP. Đây là identity federation.

Ba giao thức chính: SAML, OIDC, OAuth 2.0

Đây là phần trọng tâm. Có ba "ngôn ngữ" để các hệ thống nói chuyện với nhau về danh tính:

Giao thứcBản chấtĐịnh dạng dữ liệuUse case điển hình
SAML 2.0Xác thực liên kết (federation) cho doanh nghiệpXMLSSO nội bộ doanh nghiệp, tích hợp với AD FS, các ứng dụng B2B truyền thống
OAuth 2.0Ủy quyền truy cập tài nguyên (authorization)JSON + tokenCho phép app A truy cập dữ liệu của bạn ở app B (ví dụ "Đăng nhập bằng Facebook để lấy danh bạ")
OIDC (OpenID Connect)Xác thực xây trên nền OAuth 2.0JSON + JWTĐăng nhập web/mobile hiện đại, "Sign in with Google", ứng dụng cloud-native
Cần nhớ một điều gây nhầm lẫn kinh điển: OAuth 2.0 không phải là giao thức xác thực (authentication) — nó là giao thức ủy quyền (authorization). OAuth cấp cho ứng dụng một access token để truy cập tài nguyên, nhưng bản thân nó không nói rõ "người dùng này là ai". Vì lý do đó, OpenID Connect (OIDC) ra đời như một lớp mỏng phủ lên OAuth 2.0, bổ sung một token đặc biệt là ID Token (một JWT chứa thông tin định danh người dùng: email, tên, ID...). Nói ngắn gọn: OIDC = OAuth 2.0 + lớp định danh chuẩn hóa.

SAML hoạt động như thế nào?

SAML dùng XML để trao đổi một tài liệu gọi là SAML Assertion — một mẩu XML đã được IdP ký số, khẳng định "người dùng này đã xác thực thành công, đây là các thuộc tính của họ". Luồng điển hình (SP-initiated):

  • Người dùng truy cập ứng dụng (SP), ví dụ Salesforce.
  • SP thấy chưa đăng nhập, chuyển hướng người dùng về IdP kèm một SAML Request.
  • IdP yêu cầu người dùng đăng nhập (nếu chưa), rồi tạo SAML Assertion đã ký số.
  • Trình duyệt gửi assertion này về lại SP (thường qua HTTP POST).
  • SP kiểm tra chữ ký, thấy hợp lệ, cho người dùng vào.
SAML mạnh mẽ, chín muồi, phổ biến trong doanh nghiệp lớn. Nhược điểm: XML cồng kềnh, khó dùng cho mobile app và SPA (single-page application).

OIDC hoạt động như thế nào?

OIDC hiện đại hơn, dùng JSON và JWT, phù hợp web/mobile. Luồng phổ biến nhất là Authorization Code Flow:

  • Người dùng bấm "Sign in with Google" trên ứng dụng.
  • Ứng dụng chuyển hướng tới Google (IdP) kèm client_id, redirect_uri, scope=openid email profile.
  • Người dùng đăng nhập Google và đồng ý chia sẻ thông tin.
  • Google chuyển hướng về ứng dụng kèm một authorization code ngắn hạn.
  • Backend của ứng dụng đổi code này lấy ID Token (JWT) + Access Token từ Google qua kênh server-to-server an toàn.
  • Ứng dụng xác minh chữ ký JWT bằng khóa công khai của Google, đọc email/tên người dùng, hoàn tất đăng nhập.
ID Token là một JWT gồm ba phần: header, payload (chứa các claims như sub, email, iss, aud, exp) và chữ ký. Nhờ chữ ký, ứng dụng tin được nội dung mà không cần gọi lại IdP.

Tình huống thực tế

Tình huống 1: Startup fintech tại Hà Nội thống nhất đăng nhập bằng Google Workspace

Một startup fintech khoảng 80 người ở Hà Nội, gọi là VietPay, ban đầu để mỗi nhân viên tự tạo tài khoản riêng cho từng công cụ: GitLab self-hosted, Grafana, tài khoản AWS IAM user, và cổng nội bộ HR. Khi công ty tăng lên 80 người, đội IT chỉ có 2 người bắt đầu quá tải: mỗi lần có nhân viên nghỉ việc, họ phải nhớ đi khóa 4-5 tài khoản, và đã có lần một cựu nhân viên vẫn truy cập được Grafana sau khi nghỉ ba tuần — một rủi ro nghiêm trọng với công ty tài chính.

Giải pháp: VietPay dùng Google Workspace làm IdP trung tâm và cấu hình SSO qua OIDC cho GitLab và Grafana (cả hai đều hỗ trợ OIDC sẵn), còn AWS thì dùng federation qua SAML giữa Google Workspace và AWS IAM Identity Center. Từ đó, nhân viên chỉ đăng nhập một tài khoản Google công ty, bật MFA một lần, và truy cập tất cả. Khi ai đó nghỉ việc, IT chỉ cần suspend tài khoản Google là người đó mất quyền truy cập mọi thứ trong vòng vài phút.

Bài học rút ra: SSO không chỉ là tiện lợi — nó là công cụ kiểm soát vòng đời truy cập (access lifecycle). Với công ty tài chính chịu ràng buộc tuân thủ, khả năng "khóa một chỗ, mất quyền mọi nơi" (deprovisioning tập trung) là giá trị lớn nhất.

Tình huống 2: Nhầm lẫn OAuth và OIDC gây lỗ hổng bảo mật

Một team sản phẩm tại một công ty thương mại điện tử ở Singapore triển khai tính năng "Đăng nhập bằng Facebook". Lập trình viên, do thiếu kinh nghiệm, chỉ dùng OAuth 2.0 access token: sau khi nhận access token từ Facebook, ứng dụng gọi Graph API để lấy user ID rồi coi như người dùng đã đăng nhập thành công. Vấn đề: access token của OAuth được cấp cho một ứng dụng cụ thể, không phải cho ứng dụng của họ. Một kẻ tấn công có thể lấy access token hợp lệ do Facebook cấp cho ứng dụng khác (nơi có lỗ hổng rò rỉ token), rồi gửi vào ứng dụng thương mại điện tử này và đăng nhập thành danh tính của nạn nhân. Đây chính là lỗ hổng kinh điển mang tên "confused deputy" khi dùng OAuth để xác thực.

Sau khi bị đội security cảnh báo, team chuyển sang OIDC: dùng ID Token (JWT) thay vì access token, và bắt buộc kiểm tra claim aud (audience) đúng bằng client_id của chính ứng dụng mình. Vì ID Token được ký và có aud cố định, token cấp cho ứng dụng khác sẽ bị từ chối ngay.

Bài học rút ra: OAuth 2.0 dùng để ủy quyền truy cập tài nguyên, không phải để xác thực danh tính. Muốn "đăng nhập bằng...", hãy dùng OIDC và luôn kiểm tra chữ ký, iss, aud, exp của ID Token.

Tình huống 3: Doanh nghiệp lớn dùng SAML với Azure AD cho ứng dụng SaaS

Một tập đoàn sản xuất lớn tại Việt Nam với hơn 5.000 nhân viên dùng Microsoft 365, nên IdP tự nhiên là Azure Active Directory (nay là Microsoft Entra ID). Họ mua nhiều ứng dụng SaaS: Salesforce cho sales, Workday cho nhân sự, và một hệ thống quản lý tài liệu cũ chỉ hỗ trợ SAML.

Đội IT cấu hình SAML federation giữa Azure AD (IdP) và từng ứng dụng SaaS (SP). Họ trao đổi metadata XML chứa certificate và các endpoint, thiết lập trust một lần. Nhờ Azure AD hỗ trợ provisioning tự động qua SCIM, khi phòng nhân sự tạo nhân viên mới trong hệ thống, tài khoản tương ứng ở Salesforce và Workday được tạo tự động; khi nhân viên chuyển phòng ban, quyền truy cập cũng cập nhật theo group.

Bài học rút ra: SAML vẫn là "vua" trong môi trường doanh nghiệp lớn có sẵn Microsoft/AD, đặc biệt với các ứng dụng SaaS truyền thống. Đừng chê SAML lỗi thời — trong thực tế B2B, nó vẫn là tiêu chuẩn được yêu cầu.

Hướng dẫn từng bước

Giả sử bạn cần triển khai "Sign in with Google" (OIDC) cho một ứng dụng web nội bộ. Các bước tổng quát:

  • Đăng ký ứng dụng với IdP: Vào Google Cloud Console, tạo OAuth Client ID. Nhận về client_id và client_secret. Khai báo redirect_uri chính xác (ví dụ https://app.congty.vn/callback) — đây là nơi IdP sẽ trả người dùng về.
  • Chọn đúng flow: Với web app có backend, dùng Authorization Code Flow. Với SPA hoặc mobile, dùng Authorization Code Flow + PKCE (Proof Key for Code Exchange) để chống đánh cắp code. Tuyệt đối không dùng Implicit Flow — đã lỗi thời và kém an toàn.
  • Khai báo scope: Ít nhất cần openid. Thêm email profile nếu cần lấy email và tên. Chỉ xin đúng scope cần dùng — nguyên tắc tối thiểu đặc quyền.
  • Xử lý callback: Khi Google chuyển người dùng về kèm code, backend đổi code lấy token qua endpoint token của Google (gửi kèm client_secret).
  • Xác minh ID Token: Đây là bước sống còn. Kiểm tra chữ ký JWT bằng khóa công khai của Google (lấy từ JWKS endpoint), rồi kiểm tra iss đúng là Google, aud đúng client_id của bạn, và exp chưa hết hạn.
  • Tạo session cho ứng dụng: Sau khi tin tưởng, tạo session/cookie riêng của ứng dụng. Đừng dùng lại token của Google làm session vô thời hạn.
  • Bật MFA ở IdP: Vì mọi cửa đều mở từ một lần đăng nhập, hãy bắt buộc MFA tại Google Workspace/Azure AD. Đây là lớp bảo vệ quan trọng nhất của mô hình SSO.

Lỗi thường gặp & mẹo

  • Dùng OAuth access token để xác thực: như tình huống 2, đây là lỗi nguy hiểm nhất. Luôn dùng ID Token của OIDC cho việc đăng nhập.
  • Quên kiểm tra aud, iss, exp của JWT: một JWT hợp lệ về chữ ký nhưng cấp cho ứng dụng khác vẫn phải bị từ chối. Bỏ qua bước này mở đường cho token bị dùng chéo.
  • Không dùng thư viện chuẩn, tự parse XML/JWT: SAML và JWT có nhiều bẫy bảo mật (XML signature wrapping, thuật toán alg: none...). Luôn dùng thư viện đã được kiểm chứng, đừng tự viết bộ xác minh.
  • redirect_uri quá lỏng: nếu cho phép wildcard hoặc không khớp chính xác, kẻ tấn công có thể chiếm code. Luôn whitelist redirect_uri tuyệt đối chính xác.
  • Không xử lý Single Logout: SSO đăng nhập một lần, nhưng nhiều nơi quên đăng xuất một lần. Người dùng bấm logout ở một app nhưng session ở app khác vẫn sống — rủi ro trên máy dùng chung.
  • Mẹo — chọn giao thức đúng: Nếu xây ứng dụng web/mobile mới, chọn OIDC. Nếu tích hợp với hệ thống doanh nghiệp cũ hoặc SaaS B2B yêu cầu, dùng SAML. Nếu chỉ cần truy cập API/tài nguyên thay mặt người dùng (không cần biết họ là ai), dùng OAuth 2.0 thuần.
  • Mẹo — tập trung MFA vào IdP: đừng bắt MFA rải rác ở từng app. Đặt MFA mạnh ở IdP trung tâm là hiệu quả nhất.

Bài tập thực hành

  • Phân biệt khái niệm: Với mỗi câu sau, xác định nó thuộc AuthN hay AuthZ: (a) hệ thống kiểm tra vân tay của bạn; (b) hệ thống quyết định bạn có được xóa bucket S3 hay không; (c) bạn nhập mã OTP từ SMS.
  • Chọn giao thức: Cho ba tình huống, hãy chọn SAML, OIDC hay OAuth 2.0 và giải thích: (a) một app mobile mới cần "Đăng nhập bằng Apple"; (b) tích hợp SSO cho Salesforce trong công ty đã dùng Azure AD; (c) app của bạn cần đọc danh sách repo GitHub của người dùng thay mặt họ.
  • Vẽ luồng OIDC: Vẽ sơ đồ Authorization Code Flow cho "Sign in with Google", đánh dấu rõ bước nào diễn ra trên trình duyệt và bước nào server-to-server. Chỉ ra chính xác nơi cần xác minh chữ ký ID Token.
  • Tình huống an ninh: Một đồng nghiệp nói "app mình xác thực người dùng bằng cách nhận access token từ Facebook rồi gọi API lấy user ID, thế là đủ". Hãy viết một đoạn giải thích tại sao cách này không an toàn và cần sửa thế nào.
  • Thực hành thực tế (nâng cao): Tạo một OAuth Client ID trên Google Cloud Console (miễn phí), và dùng một thư viện OIDC bất kỳ (ví dụ trong Node.js hoặc Python) để triển khai luồng đăng nhập, in ra các claim trong ID Token. Quan sát sub, email, aud, iss, exp.

Tóm tắt

  • Authentication trả lời "bạn là ai", Authorization trả lời "bạn được làm gì". Bài này tập trung vào xác thực và liên kết định danh.
  • SSO (Single Sign-On) cho phép một lần đăng nhập truy cập nhiều dịch vụ, dựa trên sự tin tưởng giữa Identity Provider (IdP) và Service Provider (SP). Lợi ích lớn nhất là quản lý vòng đời truy cập tập trung và bật MFA một chỗ.
  • Federation mở rộng SSO ra ngoài ranh giới tổ chức — nền tảng để dùng tài khoản Google/Azure đăng nhập vào AWS, GCP.
  • SAML 2.0 dùng XML, chín muồi, phổ biến trong doanh nghiệp lớn và SaaS B2B. OAuth 2.0 là giao thức ủy quyền, không phải xác thực. OIDC xây trên OAuth 2.0, bổ sung ID Token (JWT) để xác thực hiện đại cho web/mobile.
  • Sai lầm nguy hiểm nhất là dùng OAuth access token để xác thực. Luôn dùng OIDC ID Token và kiểm tra iss, aud, exp, chữ ký.
  • Chọn giao thức theo bối cảnh: OIDC cho ứng dụng mới, SAML cho doanh nghiệp/B2B cũ, OAuth thuần khi chỉ cần truy cập tài nguyên. Luôn dùng thư viện chuẩn và tập trung MFA vào IdP.
Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi