Có rất nhiều câu hỏi ở đây liên quan đến các cơ chế xác thực và ủy quyền của API RESTful nhưng không có câu hỏi nào xuất hiện để đi vào chi tiết về cách triển khai các dịch vụ bảo mật ở cấp ứng dụng.
Ví dụ: giả sử ứng dụng web của tôi (tôi đã có Java nhưng điều này áp dụng cho bất kỳ phụ trợ nào thực sự) có hệ thống xác thực an toàn cho phép người dùng API đăng nhập bằng tên người dùng và mật khẩu. Khi người dùng đưa ra yêu cầu, tại bất kỳ thời điểm nào trong quá trình xử lý yêu cầu, tôi có thể gọi một getAuthenticatedUser()
phương thức sẽ trả về người dùng null nếu người dùng không đăng nhập hoặc đối tượng miền Người dùng đại diện cho người dùng đã đăng nhập.
API cho phép người dùng được xác thực truy cập dữ liệu của họ, ví dụ như GET /api/orders/
sẽ trả về danh sách đơn đặt hàng của người dùng đó. Tương tự, một GET để /api/tasks/{task_id}
trả về dữ liệu liên quan đến nhiệm vụ cụ thể đó.
Giả sử rằng có một số đối tượng miền khác nhau có thể được liên kết với tài khoản của người dùng (đơn hàng và tác vụ là hai ví dụ, chúng tôi cũng có thể có khách hàng, hóa đơn, v.v.). Chúng tôi chỉ muốn người dùng được xác thực có thể truy cập dữ liệu về các đối tượng của chính họ vì vậy khi người dùng thực hiện cuộc gọi đến /api/invoices/{invoice_id}
chúng tôi cần kiểm tra xem người dùng có được phép truy cập tài nguyên đó trước khi chúng tôi phục vụ không.
Câu hỏi của tôi là sau đó, các mô hình hoặc chiến lược tồn tại để giải quyết vấn đề ủy quyền này? Một tùy chọn tôi đang xem xét là tạo giao diện trợ giúp (nghĩa là SecurityUtils.isUserAuthorized(user, object)
), có thể được gọi trong quá trình xử lý yêu cầu để đảm bảo rằng người dùng được ủy quyền để tìm nạp đối tượng. Điều này không lý tưởng vì nó gây ô nhiễm mã điểm cuối của ứng dụng với nhiều cuộc gọi này, vd
Object someEndpoint(int objectId) {
if (!SecurityUtils.isUserAuthorized(loggedInUser, objectDAO.get(objectId)) {
throw new UnauthorizedException();
}
...
}
... Và sau đó là câu hỏi về việc triển khai phương pháp này cho mọi loại tên miền có thể gây ra một chút khó khăn. Đây có thể là lựa chọn duy nhất nhưng tôi rất muốn nghe đề xuất của bạn!