Thực hành tiêu chuẩn để kiểm soát truy cập (mẫu thiết kế)


9

Tôi đang xem xét thiết kế giao diện của mình và tôi đang đấu tranh để quyết định đâu là cách "chính xác" nhất để thực hiện kiểm soát truy cập dựa trên vai trò, đưa ra một uservà một subjectđiều mà chúng tôi usermuốn truy cập.


Theo như tôi có thể thấy tôi có ba tùy chọn cốt lõi (với thứ tư là một sự khốn của ba thứ nhất và một thứ năm là một tinh chỉnh của thứ tư):

  1. Truy vấn subjectdanh sách các quyền mà usercó -subject.allowAccess(user.getPermissionSet)
  2. Truy vấn userdanh sách các quyền mà subjectyêu cầu -user.hasPermissionTo(subject.getRequiredPermissions())
  3. Truy vấn bên thứ ba để xác định vị trí giao điểm của quyền - accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet())
  4. Truy vấn subject/ user, trong khi ủy thác "quyết định" cho lớp bên thứ ba
  5. usernỗ lực truy cập subjectvà ném lỗi nếu không cho phép truy cập

Tôi đang nghiêng về tùy chọn bốn - Có subjectmột accessControllertrường chứa , trong đó các lệnh gọi để subject.userMayAccess(User user)ủy quyền cho hoạt động a la:

class Subject {
    public function display(user) {
        if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
            display403(); //Or other.. eg, throw an error..
        }
    }
}

.. nhưng sau đó điều này đặt ra câu hỏi thêm:

  • nên accessControllerlà một trường so với một lớp tĩnh ..?
  • Có nên subject biết những quyền nào được yêu cầu để có thể xem nó không?
  • nguyên tắc của kiến ​​thức tối thiểu xuất hiện ở đây, liên quan đến việc gọi điện thoại ở subject.display()đâu? Người gọi có subject.display()bao giờ nên biết rằng kiểm soát truy cập có hiệu lực? (nơi subject.display()là "phương thức mẫu" cuối cùng)
  • đã subject.display()quản lý kiểm soát truy cập, đưa ra một ngoại lệ mà người dùng không có quyền yêu cầu?

Điều gì sẽ được coi là "thực hành tốt nhất" trong tình huống này? Trường hợp nào trách nhiệm để thực hiện kiểm tra thực sự xảy ra?

Vì đây phần nào là một bài tập học thuật mà sau đó sẽ tiến hành triển khai, các tài liệu tham khảo về các mẫu thiết kế sẽ được đánh giá cao.

Câu trả lời:


7

Cách thực hành tốt nhất là sử dụng một cái gì đó được gọi là mẫu Interceptor để chặn các cuộc gọi đến các khu vực được bảo vệ.

Điều này có thể đạt được bằng cách sử dụng AOP hoặc cắt ngang mối quan tâm áp dụng cho các điểm truy cập truy cập của bạn.

Chủ đề không bao giờ nên biết về người có thể xem nó. Điều này làm phức tạp mã chủ đề một cách không cần thiết và không có lý do nào để bắt buộc, trừ khi bạn vô tình cung cấp một cơ chế truy cập trực tiếp vào cùng chức năng.

Tốt nhất là người gọi và callee không nên biết về quyền truy cập, ngoài việc xử lý các từ chối. Tuy nhiên, vấn đề sẽ phụ thuộc vào hệ thống bạn đang triển khai và cách bạn có quyền truy cập vào thông tin xác thực / hiệu trưởng bảo mật cho người gọi. Ví dụ, trong các hệ thống SOAP, thông tin này được thêm vào tiêu đề của thông báo SOAP, trong khi đó trong hệ thống windows, nó sẽ có sẵn thông qua cơ chế xác thực windows.

Nếu bạn sử dụng phương pháp mô hình đánh chặn hoặc đánh chặn AOP, nó sẽ đưa ra bất kỳ trường hợp ngoại lệ cần thiết nào và nó sẽ tùy thuộc vào máy khách (người gọi) để xử lý bất kỳ trường hợp ngoại lệ nào được ném.

Theo cách này, bạn giữ cho máy khách, dịch vụ và mã xác thực của bạn tách biệt mà không xen kẽ kiến ​​thức hoặc chức năng.



2

Tôi nghĩ rằng tùy chọn 3 của bạn là gần nhất, nhưng thay vì thẩm vấn usersubjectvề các bộ quyền của họ, bạn nên chuyển usersubjectcho bộ điều khiển truy cập.

class Subject {
    public function display(user) {
        if(!accessController.checkAccess(this, user, AccessControl.Read)) {
            display403(); //Or other.. eg, throw an error..
        }
    }
}

Bộ điều khiển truy cập phải chịu trách nhiệm cho cả việc lấy các bộ quyền và kiểm tra xem quyền truy cập có đủ không. Bằng cách đó, bạn cách ly cả logic lưu trữ và logic kiểm tra trong bộ điều khiển truy cập của bạn, tách biệt với cả người dùng và chủ đề.

Yếu tố khác có thể thiếu trong ví dụ của bạn là thao tác nào đang được thực hiện. Một số người dùng có thể có quyền đọc một số dữ liệu nhưng không cập nhật, xóa, thực thi, vv Vì vậy, bạn có thể có một checkAccessphương pháp trên bộ điều khiển truy cập với ba thông số: user, subject, operation. Bạn cũng có thể muốn cung cấp một số thông tin bổ sung từ checkAccessđể trả lại thông tin về lý do tại sao quyền truy cập không được cấp.

Ví dụ: ủy quyền tất cả điều này cho bộ điều khiển truy cập sau này cho phép bạn thay thế cách thể hiện quyền của bạn. Bạn có thể bắt đầu với kiểm soát truy cập dựa trên vai trò và chuyển sang khiếu nại dựa trên sau này. Bạn có thể lưu trữ các quyền trong một cấu trúc đơn giản để bắt đầu và sau đó thêm các nhóm / vai trò phân cấp và các hoạt động được phép trên các loại đối tượng khác nhau. Không đặt các bộ quyền của bạn vào giao diện sẽ giúp kích hoạt tính năng này.

Cho dù bạn sử dụng AOP hoặc một số mã soạn sẵn để cắm mã này, theo tôi, ít quan trọng hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.