2012-03-11 31 views
12

Tôi muốn nghe một số suy nghĩ về cách tốt nhất để tối ưu hóa lược đồ của chúng tôi để đạt được những điều sau đây.Cách tốt nhất để quản lý quyền đối tượng người dùng/nhóm với Symfony2

Chúng tôi có một số đối tượng/mục db (sự kiện, địa điểm, vv) một số trong đó có trẻ em các đối tượng (có nghĩa là các điều khoản tương tự áp dụng - hình ảnh, METAS, vv)

Người dùng có thể thuộc về các nhóm để cha mẹ các đối tượng như sự kiện, địa điểm có thể chỉnh sửa/có thể xem được, chỉ nhóm, chỉ một người dùng.

Hiện tại chúng tôi có bảng người dùng, nhóm người dùng và nhóm để quản lý người dùng và nhóm.

Mỗi đối tượng mẹ như địa điểm dưới dạng cột cho user_id và group_id.

Hoạt động tốt (trong symfony 1.4) nhưng nó lộn xộn - mọi truy vấn cho mọi thứ đều phải thực hiện các phép nối phức tạp để có được các nhóm có thể, v.v ... Chúng tôi muốn tìm một cách đơn giản hơn.

Tôi thực sự vui mừng về thành phần ACL Sf2 nhưng tôi không được sử dụng nó để tìm các đối tượng mà người dùng có thể quản lý - thay vào đó tôi nên sử dụng ACL để tìm hiểu xem người dùng có được phép không để quản lý các đối tượng của riêng mình (dường như không hữu ích lắm nhưng bất cứ điều gì).

Mọi nỗ lực thay thế trực tuyến mà tôi tìm thấy để thực hiện điều này nói để kéo tất cả các đối tượng khỏi db rồi lọc theo ACL - nó dễ thương cho một trang mẹ và pop - sẽ không xảy ra với một triệu đối tượng.

Vì vậy, tôi rất muốn nghe ý tưởng về cách chúng tôi có thể làm điều này - chúng tôi cũng sẵn sàng để thoát khỏi symfony cho một thứ có giải pháp ACL có thể mở rộng nhưng chưa tìm thấy bất kỳ thứ gì (php hoặc ruby) mở cửa cho điều đó, mặc dù chúng tôi rất thích tiếp tục sử dụng Sf. Lưu ý rằng chúng tôi dự định sử dụng MongoDB trong trường hợp có vấn đề.

Trả lời

11

Từ cách tôi hiểu, ACL được sử dụng để cấp quyền truy cập vào một đối tượng cụ thể cho một người cụ thể cho các trường hợp đặc biệt. Những gì bạn mô tả là chung chung hơn, nhưng nó chỉ lệch khỏi những gì Symfony2 vạch ra cho bảo mật (người này có vai trò "quản trị", nhưng chỉ cho các đối tượng chứa trong một nhóm cụ thể).

ACL không nên được sử dụng để lưu trữ một loạt nội dung, vì việc kiểm tra xem nó có thể tốn kém không nếu nó quá lớn. Vì vậy, hãy ném một số thứ vào đây theo mặc định khi người dùng mới được thêm vào hoặc thậm chí khi các đối tượng mới được thêm vào trong nhóm (nếu sử dụng ACL, bạn sẽ phải thêm mục nhập vào từng người trong nhóm bất cứ khi nào bạn tạo đối tượng mới), sẽ tính thuế về hiệu suất sau một thời gian ...

Tôi hiện đang nghiên cứu khả năng sử dụng Symfony2 cho ứng dụng web, nhưng tôi cũng đang đánh một bức tường với công cụ bảo mật này một nhu cầu tương tự. Tôi không có chuyên gia về Symfony2, nhưng từ những gì tôi đã xem xét, bạn có thể có một vài tùy chọn:

  1. Tạo một cử tri để xử lý việc này. Cử tri cho phép bạn kiểm tra mã thông báo ủy quyền và trả lại xem quyền truy cập được cấp hay bị từ chối dựa trên cách bạn xử lý nó. Vì vậy, bạn có thể làm cho một cử tri tùy chỉnh kiểm tra nhóm của người dùng và cố gắng kết hợp nó với nhóm đối tượng đang ở dưới. Nếu vậy, hãy trả lại ACCESS_GRANTED, nếu không ACCESS_DENIED hoặc ACCESS_ABSTAIN nếu Cử tri không hợp lệ cho séc hiện tại. EDIT: Đây là một liên kết đến cuốn sách nấu ăn Symfony2 cho cử tri:

  2. Cũng có thể muốn nghiên cứu giao diện SecurityContext. Điều này cung cấp phương thức "isGranted()" liên quan đến việc xác định quyền truy cập vào các đối tượng.Nếu cử tri không đơn giản là đủ, bạn có thể phải đi con đường tạo ra một lớp SecurityContext mới; Tôi nghĩ rằng điều này sẽ được tham gia nhiều hơn một chút mặc dù.

Như tôi đã nói, tôi không chuyên nghiệp và không có giải pháp; đây chỉ là một số hướng tôi đang nghiên cứu để cố gắng giải quyết (những gì tôi cảm thấy là) một vấn đề tương tự. Hy vọng điều này sẽ giúp phần nào.

1

Nó được một lúc kể từ khi tôi đăng câu trả lời ban đầu của tôi với điều này, nhưng muốn theo dõi với một giải pháp, một mà chúng tôi đang sử dụng.

Mặc dù Symfony cung cấp lớp bảo mật/ACL để sử dụng, bạn không để sử dụng hoặc ít nhất là đầy đủ.

Tại chỉ là về bất kỳ thời điểm nào trong mã của bạn, bạn có thể ném một lớp an ninh Symfony\Component\Security\Core\Exception\AccessDeniedException và sẽ "đá trong" và xử lý nó cho bạn, như chuyển hướng người dùng đến một trang đăng nhập, vv

Một số tương tác này có thể yêu cầu thiết lập tường lửa nâng cao hơn một chút để hoạt động chính xác theo cách bạn muốn.

Câu chuyện dài ngắn, trong khi Symfony cung cấp một số cơ chế và tính năng tuyệt vời để giúp xây dựng ACL, bạn không phải làm việc để phù hợp với dữ liệu và quy trình của mình vào những gì họ đã xác định.

Đối với hệ thống của chúng tôi là một ví dụ, chúng tôi có tài khoản, Vai trò, và nhóm trong hệ thống của chúng tôi (cùng với Quyền). Chúng tôi cũng chia các phần dữ liệu ra thành các phòng ban. Mặc dù người dùng có thể có Vai trò và quyền cấp độ toàn cầu nhưng họ cũng có thể có quyền truy cập cụ thể theo từng Bộ. Thiết lập này được thực hiện bằng cách sử dụng các tính năng của Symfony ACL và các công cụ kiểm tra truy cập gần như không sử dụng được (không có nghĩa là các công cụ của họ vô ích, chúng thực sự tuyệt vời, chúng không phù hợp với trường hợp sử dụng của chúng ta). Vì vậy, chúng tôi đã xây dựng dịch vụ riêng của mình (sử dụng một số truy vấn được tinh chỉnh), nơi chúng tôi chuyển các dữ liệu liên quan đến séc và nó ném Symfony\Component\Security\Core\Exception\AccessDeniedException thích hợp khi séc không thành công.

Các vấn đề liên quan