Hai câu hỏi, hai chỗ trả lời
Xác thực (authentication) trả lời bạn là ai. Đầu vào là một bằng chứng — mật khẩu, passkey, token — và đầu ra là một danh tính. Nó xảy ra một lần cho mỗi request, ở middleware, và nó không biết gì về dữ liệu request đang chạm tới.
Phân quyền (authorisation) trả lời bạn được làm gì. Đầu vào là một danh tính cộng với một đối tượng cụ thể, và đầu ra là cho phép hoặc từ chối. Nó xảy ra mỗi lần chạm tới một đối tượng, ở tầng nghiệp vụ hoặc tầng truy vấn.
Điểm quan trọng nhất và cũng là chỗ hay nhầm nhất: middleware không thể trả lời câu hỏi thứ hai. [Authorize] biết Bob là Bob. Nó không biết 1042 là gì, không biết 1042 có phải của Bob, và không có chỗ nào cho nó biết — thông tin đó nằm trong cơ sở dữ liệu. Đó là lý do một endpoint có thể có [Authorize] đầy đủ và vẫn cho đọc dữ liệu người khác.
Có một câu hỏi thứ ba mà đôi khi được gọi lẫn là phân quyền: bạn có vai gì. [Authorize(Roles = "Admin")] trả lời câu này, và nó là phân quyền — nhưng chỉ ở mức hàm (API5, "được gọi endpoint này không"), không phải mức đối tượng (API1, "được đọc bản ghi này không"). Hai mức, hai bản vá khác nhau, và một hệ thống cần cả hai.
| Câu hỏi | Tên | Vị trí trong code | Sai thì gọi là |
|---|---|---|---|
| Bạn là ai? | Authentication | Middleware, một lần mỗi request | A07 Authentication Failures |
| Bạn được gọi hàm này không? | Function-level authz | Attribute hoặc policy trên action | API5 / BFLA |
| Bạn được chạm đối tượng này không? | Object-level authz | Trong truy vấn, mỗi lần truy cập | API1 / BOLA / IDOR |
Bình luận
Bình luận cần tài khoản đã hoàn thành ít nhất một bài học. Điều kiện đó là thứ giữ cho luồng thảo luận này còn đáng đọc: mỗi ý kiến gắn với một người có thể bị hỏi lại, và reputation tích luỹ theo thời gian.
Bạn vẫn đọc được toàn bộ bình luận dưới đây mà không cần tài khoản. Đăng nhập xong bạn sẽ quay lại đúng chỗ này, không phải đầu trang.
Đang tải bình luận…