1

[img_assist | nid = 3998 | title = | desc = | link = url | url = http: //www.amazon.com / exec | height = 240] Bây giờ chúng tôi có một số ý tưởng về cơ sở dữ liệu, chúng tôi nhanh chóng chạy vào một yêu cầu khác. Nhiều trang web sẽ muốn kiểm soát ai có quyền truy cập vào những gì. Khi bắt tay vào tuyến đường này, hóa ra có nhiều tình huống kiểm soát truy cập là phù hợp và chúng có thể dễ dàng trở nên rất phức tạp. Vì vậy, trong chương này, chúng tôi xem xét kiểm soát truy cập dựa trên mô hình được đánh giá cao nhất và tìm cách triển khai nó. Mục đích là để đạt được một triển khai linh hoạt và hiệu quả có thể được khai thác bằng phần mềm ngày càng tinh vi. Để hiển thị những gì đang diễn ra, ví dụ về phần mở rộng kho lưu trữ tệp được sử dụng.

Vấn đề

Chúng ta cần thiết kế và triển khai hệ thống kiểm soát truy cập dựa trên vai trò (RBAC), thể hiện việc sử dụng nó và đảm bảo rằng hệ thống có thể cung cấp:

  • một cấu trúc dữ liệu đơn giản
  • một mã linh hoạt để cung cấp giao diện RBAC có thể sử dụng
  • hiệu quả để RBAC tránh được chi phí nặng


Thảo luận và cân nhắc

Hệ thống máy tính có các điều khiển cần thiết từ lâu khi truy cập. Phần mềm ban đầu thường rơi vào danh mục được gọi là danh sách kiểm soát truy cập (ACL). Nhưng chúng thường được áp dụng ở mức khá thấp trong các hệ thống và được gọi là các hoạt động cơ bản của máy tính. Phát triển hơn nữa mang lại phần mềm được thiết kế để giải quyết các vấn đề chung hơn, chẳng hạn như kiểm soát các tài liệu liên quan đến confi. Nhiều công việc đã được thực hiện trên điều khiển truy cập tùy ý (DAC) và kiểm soát truy cập bắt buộc (MAC).

Một lượng lớn các nghiên cứu học thuật đã được dành cho toàn bộ câu hỏi về kiểm soát truy cập. Đỉnh cao của công việc này là mô hình được ưa chuộng rộng rãi nhất là hệ thống kiểm soát truy cập dựa trên vai trò, một câu cửa miệng mà từ viết tắt RBAC được sử dụng sau đây. Bây giờ mặc dù phân tích học thuật có thể là tóm tắt, chúng ta cần một giải pháp thiết thực cho vấn đề quản lý quyền truy cập vào các dịch vụ trên một trang web. May mắn thay, giống như cơ sở dữ liệu quan hệ được thảo luận trong chương trước, các khái niệm về RBAC là đủ đơn giản.

RBAC liên quan đến một số thực thể cơ bản. Thật không may, các thuật ngữ không phải lúc nào cũng nhất quán, vì vậy chúng ta hãy theo sát xu hướng chính và một số thuật ngữ sẽ được sử dụng để thực hiện giải pháp của chúng tôi:

  • Chủ đề: Một chủ đề là một cái gì đó được kiểm soát. Nó có thể là toàn bộ trang web, nhưng cũng có thể là một cái gì đó đặc biệt hơn nhiều như một thư mục trong hệ thống kho lưu trữ. Ví dụ này chỉ ra thực tế rằng một chủ đề thường có thể được chia thành hai yếu tố, một loại và một nhận dạng er. Vì vậy, các thư mục của kho lưu trữ được tính là một loại chủ đề và mỗi thư mục riêng lẻ có một số loại nhận dạng.
  • Hành động: Một hành động phát sinh bởi vì chúng ta thường cần phải làm nhiều hơn là chỉ cho phép hoặc từ chối truy cập vào các chủ đề RBAC. Trong ví dụ của chúng tôi, chúng tôi có thể đặt các hạn chế khác nhau trong việc tải lên tệp vào thư mục và tải xuống tệp từ thư mục. Do đó, hành động của chúng tôi có thể bao gồm 'tải lên' và 'tải xuống'.
  • Người truy cập : Ví dụ đơn giản nhất của người truy cập là người dùng. Người truy cập là ai đó hoặc một cái gì đó muốn thực hiện một hành động. Nó là quá hạn chế để cho rằng người truy cập luôn luôn là người dùng. Chúng tôi có thể muốn coi các hệ thống máy tính khác là người truy cập hoặc người truy cập có thể là một phần mềm cụ thể. Phụ kiện giống như các đối tượng trong việc chia thành hai phần. Phần đầu tiên là loại người truy cập, với người dùng trang web là loại phổ biến nhất. Phần thứ hai là một nhận dạng er cho bộ truy cập specifi c, có thể là số nhận dạng người dùng.
  • Quyền: Sự kết hợp của một chủ đề và một hành động là một sự cho phép. Vì vậy, ví dụ, việc có thể tải xuống từ một thư mục cụ thể trong kho lưu trữ sẽ là một sự cho phép.
  • Chuyển nhượng: Trong RBAC không bao giờ có liên kết trực tiếp giữa người truy cập và quyền để thực hiện một hành động trên một chủ đề. Thay vào đó, người truy cập được phân bổ một hoặc nhiều vai trò. Sự liên kết của một người truy cập và vai trò là một nhiệm vụ.
  • Vai trò: Vai trò là người mang các quyền và tương tự như khái niệm của một nhóm. Đó là vai trò được cấp một hoặc nhiều quyền.

Thật dễ dàng để thấy rằng chúng ta có thể kiểm soát những gì có thể được thực hiện bằng cách phân bổ vai trò cho người dùng và sau đó kiểm tra xem liệu bất kỳ vai trò nào của người dùng có quyền cụ thể không. Hơn nữa, chúng tôi có thể khái quát điều này ngoài người dùng sang các loại trình truy cập khác khi có nhu cầu. Mô hình được xây dựng cho đến nay được biết đến trong tài liệu học thuật là RBAC.

Thêm phân cấp

Vì RBAC có thể hoạt động ở cấp độ tổng quát hơn nhiều so với ACL, nên sẽ thường xảy ra một vai trò khác. Giả sử chúng ta nghĩ về ví dụ của một bệnh viện, vai trò của nhà tư vấn có thể bao gồm vai trò của bác sĩ. Không phải ai có vai trò bác sĩ cũng sẽ có vai trò tư vấn. Nhưng tất cả các chuyên gia tư vấn là bác sĩ.

Hiện tại, Aliro thực hiện hệ thống phân cấp hoàn toàn để tương thích ngược với Mambo và Joomla! đề án, trong đó có một hệ thống phân cấp vai trò chặt chẽ cho ACL. Khả năng mở rộng hệ thống phân cấp nói chung là khả thi, do triển khai Aliro và có thể được thêm vào một lúc nào đó.

Mô hình với việc bổ sung phân cấp vai trò được gọi là RBAC.

Thêm các ràng buộc

Trong xử lý dữ liệu chung, các tình huống phát sinh trong đó RBAC dự kiến ​​sẽ thực hiện các ràng buộc về phân bổ vai trò. Một ví dụ điển hình là cùng một người không được phép có cả vai trò quản lý tài khoản và mua hàng. Hạn chế của loại này xuất phát từ các nguyên tắc khá rõ ràng để giới hạn phạm vi cho gian lận.

Mặc dù các ràng buộc có thể là sự bổ sung mạnh mẽ cho RBAC, nhưng chúng không thường phát sinh trong các ứng dụng web, vì vậy Aliro hiện không cung cấp bất kỳ khả năng nào cho các ràng buộc. Tùy chọn này không bị loại trừ, vì các ràng buộc thường được ghép trên đầu hệ thống RBAC không có chúng.

Việc thêm các ràng buộc vào mô hình RBAC cơ bản sẽ tạo ra một mô hình RBAC2 và nếu cả hai phân cấp và các ràng buộc được cung cấp, mô hình đó được gọi là RBAC.

Tránh các hạn chế không cần thiết

Khi nói đến việc thiết kế một triển khai, sẽ thật đáng tiếc khi tạo ra những trở ngại sẽ gây rắc rối về sau. Để đạt được tính linh hoạt tối đa, một vài hạn chế được đặt trên thông tin được lưu trữ bởi hệ thống RBAC.

Đối tượng và người truy cập có cả hai loại và người nhận dạng. Các loại có thể là chuỗi và không cần hệ thống RBAC giới hạn những gì có thể được sử dụng trong khía cạnh này. Một giới hạn vừa phải về chiều dài không quá hạn chế. Tùy thuộc vào CMS rộng hơn để quyết định, ví dụ, loại đối tượng nào là cần thiết. Ví dụ của chúng tôi cho chương này là kho lưu trữ và các chủ đề mà nó cần được biết đến với người thiết kế kho lưu trữ. Tất cả các yêu cầu đến hệ thống RBAC từ kho lưu trữ sẽ xem xét kiến ​​thức này.

Số nhận dạng thường sẽ là các số đơn giản, có thể được lấy từ khóa chính tăng tự động trong cơ sở dữ liệu. Nhưng nó sẽ bị hạn chế quá mức để khẳng định rằng người nhận dạng phải là số. Có thể là sự kiểm soát là cần thiết đối với các đối tượng không thể được nhận dạng bởi một số. Có thể chủ đề chỉ có thể được nhận dạng bởi một khóa không có chữ số như URI hoặc có thể nó cần nhiều hơn một trường để chọn nó.

Vì những lý do này, tốt hơn là triển khai hệ thống RBAC với các bộ nhận dạng dưới dạng chuỗi, có thể với các ràng buộc độ dài khá hào phóng. Theo cách đó, các nhà thiết kế phần mềm sử dụng hệ thống RBAC có cơ hội tối đa để xây dựng các bộ nhận dạng hoạt động trong một bối cảnh cụ thể. Bất kỳ số lược đồ nào cũng có thể được tưởng tượng sẽ kết hợp nhiều trường thành một chuỗi; Rốt cuộc, điều duy nhất chúng ta sẽ làm với nhận dạng er trong hệ thống RBAC là kiểm tra sự bằng nhau. Được cung cấp nhận dạng là duy nhất, cấu trúc chính xác của chúng không thành vấn đề. Điểm duy nhất để xem là đảm bảo rằng bất kể định danh gốc có thể là gì, nó luôn được chuyển đổi thành một chuỗi.

Các hành động có thể là các chuỗi đơn giản, vì chúng chỉ là các nhãn tùy ý. Một lần nữa, ý nghĩa của chúng chỉ quan trọng trong khu vực đang áp dụng RBAC, vì vậy hệ thống RBAC thực tế không cần phải áp đặt bất kỳ hạn chế nào. Chiều dài không cần phải đặc biệt lớn.

Vai trò tương tự nhau, mặc dù các hệ thống đôi khi bao gồm một bảng vai trò vì thông tin bổ sung được giữ, chẳng hạn như mô tả về vai trò. Nhưng vì đây không thực sự là một yêu cầu của RBAC, nên hệ thống được xây dựng ở đây sẽ không yêu cầu mô tả cho các vai trò và sẽ cho phép vai trò trở thành bất kỳ chuỗi tùy ý nào. Mặc dù các mô tả có thể hữu ích, thật dễ dàng để cung cấp chúng như một phần phụ tùy chọn. Tránh làm cho chúng trở thành một yêu cầu giữ cho hệ thống càng rõ ràng càng tốt, và làm cho việc tạo vai trò trở nên dễ dàng hơn nhiều, điều gì đó thường sẽ cần thiết.

Một số vai trò đặc biệt

Xử lý các điều khiển truy cập có thể được thực hiện dễ dàng và hiệu quả hơn bằng cách phát minh ra một số vai trò có các thuộc tính đặc biệt của riêng chúng. Aliro sử dụng ba trong số này: khách truy cập, đã đăng ký và không ai.

Tất cả những người đến với trang web đều được tính là khách truy cập và do đó, mặc nhiên được trao cho khách truy cập vai trò. Nếu một quyền được trao cho vai trò này, người ta cho rằng nó được trao cho mọi người. Rốt cuộc, việc trao quyền cho khách truy cập là không hợp lý và từ chối nó cho người dùng đã đăng nhập, vì người dùng có thể có quyền truy cập chỉ bằng cách đăng xuất.

Vì lợi ích của việc thực hiện vai trò của khách truy cập, hai việc đã được thực hiện. Một là không có gì được lưu trữ để liên kết người dùng cụ thể với vai trò, vì mọi người đều có nó tự động. Thứ hai, vì hầu hết các trang web cung cấp khá nhiều quyền truy cập cho khách truy cập trước khi đăng nhập, vai trò của khách truy cập được cấp quyền truy cập vào bất kỳ thứ gì không được kết nối với một số vai trò cụ thể hơn. Điều này có nghĩa, một lần nữa, không có gì cần phải được lưu trữ liên quan đến vai trò của khách truy cập.

Hầu như vai trò đã được đăng ký, được áp dụng tự động cho bất kỳ ai đã đăng nhập, nhưng loại trừ khách truy cập chưa đăng nhập. Một lần nữa, không có gì được lưu trữ để liên kết người dùng với vai trò, vì nó áp dụng cho bất kỳ ai tự nhận mình là một người dùng đã đăng ký. Nhưng trong trường hợp này, quyền có thể được cấp cho vai trò đã đăng ký. Thay vì vai trò của khách truy cập, logic ra lệnh rằng nếu quyền truy cập được cấp cho tất cả người dùng đã đăng ký, bất kỳ quyền cụ thể nào khác đều dư thừa và có thể bị bỏ qua.

Cuối cùng, vai trò của "không ai" là hữu ích vì theo nguyên tắc không có quyền truy cập cụ thể nào được cấp, mọi người đều có sẵn tài nguyên. Khi tất cả quyền truy cập bị chặn, thì quyền truy cập có thể được cấp cho "không ai" và không người dùng nào được phép là "không ai". Trên thực tế, hiện tại chúng ta có thể thấy rằng không có người dùng nào có thể được phân bổ cho bất kỳ vai trò đặc biệt nào vì chúng luôn được liên kết với chúng một cách tự động hoặc hoàn toàn không.

Hiệu quả thực hiện

Rõ ràng một hệ thống RBAC có thể phải xử lý rất nhiều dữ liệu. Đáng chú ý hơn, nó có thể cần phải xử lý rất nhiều yêu cầu trong một thời gian ngắn. Một trang đầu ra thường sẽ bao gồm nhiều yếu tố, bất kỳ hoặc tất cả trong số đó có thể liên quan đến các quyết định truy cập.

Một cách tiếp cận hai hướng có thể được thực hiện cho vấn đề này, sử dụng hai loại bộ đệm khác nhau. Một số dữ liệu RBAC nói chung về bản chất, một ví dụ rõ ràng là hệ thống phân cấp vai trò. Điều này áp dụng như nhau cho tất cả mọi người, và là một lượng dữ liệu tương đối nhỏ. Thông tin thuộc loại này có thể được lưu trong bộ nhớ cache để có sẵn cho mọi yêu cầu.

Nhiều thông tin RBAC được liên kết với người dùng cụ thể. Nếu tất cả dữ liệu đó được lưu trữ trong bộ đệm tiêu chuẩn, có khả năng bộ đệm sẽ phát triển rất lớn, với nhiều dữ liệu không liên quan đến bất kỳ yêu cầu cụ thể nào. Một cách tiếp cận tốt hơn là lưu trữ dữ liệu RBAC cụ thể cho người dùng dưới dạng dữ liệu phiên. Bằng cách đó, nó sẽ có sẵn cho mọi yêu cầu của cùng một người dùng, nhưng sẽ không bị lộn xộn với dữ liệu cho những người dùng khác. Vì Aliro đảm bảo rằng có một phiên trực tiếp cho mọi người dùng, bao gồm cả khách truy cập chưa đăng nhập và cũng giữ nguyên dữ liệu phiên khi đăng nhập, đây là một cách tiếp cận khả thi.

Đâu là những khó khăn thực sự?

Có thể bạn nghĩ rằng chúng ta đã có đủ vấn đề để giải quyết mà không cần tìm người khác? Một thực tế đáng buồn là chúng ta thậm chí còn chưa được coi là giáo phái diffi nhất! Theo kinh nghiệm của tôi, các văn hóa diffi thực sự nảy sinh khi cố gắng thiết kế giao diện người dùng để giải quyết các yêu cầu kiểm soát thực tế.

Ví dụ được sử dụng trong chương này tương đối đơn giản. Kiểm soát những gì người dùng có thể làm trong một phần mở rộng kho lưu trữ không ngay lập tức giới thiệu nhiều sự phức tạp. Nhưng tình huống rõ ràng đơn giản này dễ dàng trở nên phức tạp hơn bởi các loại yêu cầu thường được thực hiện cho một kho lưu trữ nâng cao hơn.

Trong trường hợp đơn giản, tất cả những gì chúng tôi phải lo lắng là chúng tôi có quyền kiểm soát các khu vực của kho lưu trữ, cho biết ai có thể tải lên, ai có thể tải xuống và ai có thể chỉnh sửa tập tin. Đó là những yêu cầu được bao phủ bởi các ví dụ dưới đây.

Tuy nhiên, vượt qua điều đó, xem xét một tình huống thường được thảo luận là một yêu cầu có thể. Kho lưu trữ được mở rộng để một số người dùng có khu vực riêng của họ và có thể làm những gì họ thích trong đó. Một hậu quả đơn giản của việc này là chúng ta cần có khả năng cấp cho những người dùng đó khả năng tạo các thư mục mới trong kho lưu trữ, cũng như tải lên và chỉnh sửa các thư mục hiện có. Càng xa càng tốt! Nhưng kịch bản này cũng đưa ra ý tưởng rằng chúng tôi có thể muốn người dùng sở hữu một khu vực của kho lưu trữ có thể có quyền kiểm soát đối với các khu vực nhất định mà những người dùng khác có thể có quyền truy cập. Bây giờ chúng tôi cần khả năng bổ sung để kiểm soát người dùng nào có quyền cấp quyền truy cập vào một số phần nhất định của kho lưu trữ. Nếu chúng ta muốn đi xa hơn nữa,

Xử lý các yêu cầu kỹ thuật ở đây không phải là quá khác biệt. Điều khác biệt là giáo phái thiết kế giao diện người dùng để đối phó với tất cả các khả năng mà không tạo ra sự bùng nổ của sự phức tạp. Đối với một trường hợp riêng lẻ, việc tìm giải pháp là khả thi. Một nỗ lực để tạo ra một giải pháp chung có thể sẽ dẫn đến một vấn đề cực kỳ khó giải quyết.

Giải pháp khung

Việc thực hiện kiểm soát truy cập rơi vào ba lớp. Một là lớp học được đặt câu hỏi về ai có thể làm gì. Kết hợp chặt chẽ với điều này là một lớp khác lưu trữ thông tin chung áp dụng cho tất cả người dùng. Nó được tạo thành một lớp riêng để hỗ trợ thực hiện phân chia bộ đệm giữa generalD và specifi c. Lớp thứ ba xử lý các hoạt động quản trị. Tuy nhiên, trước khi nhìn vào các lớp, hãy tìm hiểu thiết kế cơ sở dữ liệu.

Cơ sở dữ liệu cho RBAC

Tất cả những gì cần thiết để thực hiện RBAC cơ bản là hai bảng. Cần có bảng thứ ba để mở rộng sang mô hình phân cấp. Một bảng phụ tùy chọn có thể được thực hiện để giữ các mô tả vai trò. Suy nghĩ lại về các cân nhắc thiết kế, nhu cầu đầu tiên là cách ghi lại các hoạt động có thể được thực hiện trên các đối tượng, đó là các quyền. Chúng là mục tiêu cho hệ thống kiểm soát truy cập của chúng tôi. Bạn sẽ nhớ lại rằng một quyền bao gồm một hành động và một chủ đề, trong đó một chủ đề được xác định bởi một loại và một nhận dạng er. Để dễ xử lý, số ID tăng tự động đơn giản được thêm vào. Nhưng chúng ta cũng cần một vài thứ khác.

Để làm cho hệ thống RBAC của chúng tôi trở nên chung chung, điều quan trọng là có thể kiểm soát không chỉ các quyền thực tế mà còn cả những người có thể cấp các quyền đó và liệu họ có thể cấp quyền đó cho người khác hay không. Vì vậy, một điều khiển bổ sung được thêm vào với một bit cho mỗi ba khả năng đó. Do đó, có thể cấp quyền truy cập một cái gì đó có hoặc không có khả năng truyền quyền đó.

Mục dữ liệu bổ sung khác hữu ích là "hệ thống". Nó được sử dụng để làm cho một số quyền không có khả năng xóa. Mặc dù không phải là một yêu cầu hợp lý, đây chắc chắn là một yêu cầu thực tế. Chúng tôi muốn cung cấp cho các quản trị viên nhiều quyền lực đối với các quyền truy cập, nhưng đồng thời, chúng tôi muốn tránh mọi thảm họa. Loại điều rất không mong muốn sẽ dành cho quản trị viên cấp cao nhất để xóa tất cả các quyền của riêng họ đối với hệ thống. Trong thực tế, hầu hết các hệ thống sẽ có cấu trúc quyền trung tâm quan trọng, không nên bị thay đổi ngay cả bởi người quản trị cao nhất.

Vì vậy, bây giờ bảng quyền có thể được nhìn thấy như được hiển thị trong ảnh chụp màn hình sau:

[img_assist | nid = 3993 | title = | desc = | link = none | align = none | width = 282 | height = 201]

Lưu ý rằng các chuỗi ký tự cho vai trò, hành động và chủ đề_type được cung cấp độ dài hào phóng là 60, sẽ là quá đủ. ID chủ đề thường sẽ khá ngắn, nhưng để tránh hạn chế tính tổng quát, nó được tạo thành một văn bản, để hệ thống RBAC vẫn có thể xử lý các định danh rất phức tạp, nếu cần. Tất nhiên, sẽ có một số hình phạt về hiệu suất nếu trường này rất dài, nhưng tốt hơn là nên đánh đổi thiết kế hơn là giới hạn. Nếu chúng tôi giới hạn ID chủ đề là một số, thì số nhận dạng phức tạp hơn sẽ là trường hợp đặc biệt. Điều này sẽ phá hủy tính tổng quát của chương trình của chúng tôi, và cuối cùng có thể làm giảm hiệu quả tổng thể. Ngoài ID khóa chính tăng tự động, hai chỉ số được tạo, như thể hiện trong ảnh chụp màn hình sau. Chúng liên quan đến chi phí trong quá trình hoạt động cập nhật nhưng có khả năng tăng tốc các hoạt động truy cập. Vì nhiều truy cập thường sẽ được thực hiện hơn các bản cập nhật, điều này có ý nghĩa. Nếu vì một lý do nào đó, một chỉ mục không mang lại lợi ích, thì luôn có thể bỏ nó. Lưu ý rằng chỉ mục trên ID chủ đề phải được giới hạn độ dài để tránh phá vỡ giới hạn về kích thước khóa. Giá trị được lựa chọn là sự thỏa hiệp giữa hiệu quả thông qua các khóa ngắn và hiệu quả thông qua việc sử dụng các khóa hạt. Trong một hệ thống được sử dụng nhiều, sẽ đáng để xem xét kỹ lưỡng lựa chọn và có thể sửa đổi nó dưới ánh sáng của các nghiên cứu thành dữ liệu thực tế. Lưu ý rằng chỉ mục trên ID chủ đề phải được giới hạn độ dài để tránh phá vỡ giới hạn về kích thước khóa. Giá trị được lựa chọn là sự thỏa hiệp giữa hiệu quả thông qua các khóa ngắn và hiệu quả thông qua việc sử dụng các khóa hạt. Trong một hệ thống được sử dụng nhiều, sẽ đáng để xem xét kỹ lưỡng lựa chọn và có thể sửa đổi nó dưới ánh sáng của các nghiên cứu thành dữ liệu thực tế. Lưu ý rằng chỉ mục trên ID chủ đề phải được giới hạn độ dài để tránh phá vỡ giới hạn về kích thước khóa. Giá trị được lựa chọn là sự thỏa hiệp giữa hiệu quả thông qua các khóa ngắn và hiệu quả thông qua việc sử dụng các khóa hạt. Trong một hệ thống được sử dụng nhiều, sẽ đáng để xem xét kỹ lưỡng lựa chọn và có thể sửa đổi nó dưới ánh sáng của các nghiên cứu thành dữ liệu thực tế.

[img_assist | nid = 3994 | title = | desc = | link = none | align = none | width = 519 | height = 250]

Bảng cơ sở dữ liệu chính khác thậm chí còn đơn giản hơn và chứa thông tin về việc gán người truy cập vào các vai trò. Một lần nữa, ID tăng tự động được thêm vào để thuận tiện. Ngoài ID, các trường duy nhất được yêu cầu là vai trò, loại người truy cập và ID người truy cập. Lần này, một chỉ mục duy nhất, bổ sung cho khóa chính, là đủ. Bảng gán được hiển thị trong ảnh chụp màn hình sau và chỉ mục của nó được hiển thị trong ảnh chụp màn hình sau đó:

[img_assist | nid = 3995 | title = | desc = | link = none | align = none | width = 277 | height = 128]

[img_assist | nid = 3996 | title = | desc = | link = none | align = none | width = 537 | height = 151]

Việc thêm hệ thống phân cấp vào RBAC chỉ cần một bảng rất đơn giản, trong đó mỗi hàng chứa hai trường: một vai trò và một vai trò ngụ ý. Cả hai trường đều tạo thành khóa chính, không phải trường nào cũng là duy nhất. Một chỉ số là không cần thiết cho hiệu quả, vì khối lượng thông tin phân cấp được giả định là nhỏ và bất cứ khi nào cần thiết, toàn bộ bảng được đọc. Nhưng nó vẫn là một nguyên tắc tốt để có một khóa chính và nó cũng đảm bảo rằng sẽ không có các mục thừa. Đối với ví dụ được đưa ra trước đó, một mục tiêu điển hình có thể có vai trò tư vấn và bác sĩ là vai trò ngụ ý. Hiện tại, Aliro chỉ thực hiện phân cấp để tương thích ngược, nhưng đây là một sự phát triển tương đối dễ dàng để tạo ra các mối quan hệ phân cấp nói chung.

Về mặt quang học, một bảng phụ có thể được sử dụng để giữ mô tả về các vai trò đang sử dụng. Điều này không có mục đích chức năng và chỉ đơn giản là một tùy chọn để hỗ trợ quản trị viên của hệ thống. Bảng phải có vai trò là khóa chính của nó. Vì nó hoàn toàn không ảnh hưởng đến chức năng của RBAC, nên không có thêm thông tin chi tiết nào được đưa ra ở đây.

Với thiết kế cơ sở dữ liệu được giải quyết, chúng ta hãy nhìn vào các lớp. Đơn giản nhất là lớp quản trị, vì vậy chúng ta sẽ bắt đầu ở đó.

Quản trị RBAC

Việc quản trị hệ thống có thể được thực hiện bằng cách viết trực tiếp vào cơ sở dữ liệu, vì đó là điều mà hầu hết các hoạt động liên quan. Có những lý do mạnh mẽ để không làm như vậy. Mặc dù các thao tác rất đơn giản, nhưng điều quan trọng là chúng phải được xử lý chính xác. Nhìn chung, nguyên tắc kém là cho phép truy cập vào các cơ chế của hệ thống thay vì cung cấp giao diện thông qua các phương thức lớp. Cách tiếp cận thứ hai lý tưởng cho phép tạo ra một giao diện mạnh mẽ thay đổi tương đối không thường xuyên, trong khi các chi tiết thực hiện có thể được sửa đổi mà không ảnh hưởng đến phần còn lại của hệ thống.

Lớp quản trị được tách biệt với các lớp xử lý các câu hỏi về quyền truy cập vì đối với hầu hết các yêu cầu CMS, sẽ không cần quản trị và lớp quản trị sẽ không tải gì cả. Là một dịch vụ trung tâm, lớp được triển khai như một singleton tiêu chuẩn, nhưng nó không được lưu trong bộ nhớ cache vì thông tin thường cần phải được ghi ngay vào cơ sở dữ liệu. Trong thực tế, lớp quản trị thường yêu cầu lớp bộ đệm ủy quyền xóa bộ đệm của nó để những thay đổi trong cơ sở dữ liệu có thể có hiệu lực ngay lập tức. Lớp học bắt đầu:

class aliroAuthorisationAdmin
{
	private static $instance = __CLASS__;
	private $handler = null;
	private $authoriser = null;
	private $database = null;
	private function __construct()
{
	$this->handler =& aliroAuthoriserCache::getInstance();
	$this->authoriser =& aliroAuthoriser::getInstance();
	$this->database = aliroCoreDatabase::getInstance();
}
private function __clone()
{
	// Enforce singleton
}
public static function getInstance()
{
	return is_object(self::$instance) ? self::$instance :
	(self::$instance = new self::$instance());
}
private function doSQL($sql, $clear=false)
{
	$this->database->doSQL($sql);
	if ($clear) $this->clearCache();
}
private function clearCache()
{
	$this->handler->clearCache();
}

Ngoài thuộc tính cá thể được sử dụng để triển khai mẫu singleton, các thuộc tính riêng tư khác là các đối tượng liên quan được thu nhận trong hàm tạo để trợ giúp các phương thức khác. Bắt một cá thể hoạt động theo cách thông thường cho một người độc thân, với hàm tạo riêng và các phương thức sao chép chỉ thực thi quyền truy cập thông qua getInstance.

Phương thức doQuery cũng đơn giản hóa các phương thức khác bằng cách kết hợp một cuộc gọi đến cơ sở dữ liệu với việc xóa bộ nhớ cache tùy chọn thông qua phương thức ClearCache của lớp. Rõ ràng cái sau đủ đơn giản để có thể loại bỏ. Nhưng tốt hơn là nên áp dụng phương thức này để nếu các thay đổi được thực hiện để thực hiện sao cho cần có các hành động khác nhau khi xóa bất kỳ bộ đệm có liên quan nào, các thay đổi sẽ được tách ra thành phương thức clearCache. Tiếp theo, chúng ta có một vài phương thức hữu ích chỉ cần tham khảo một trong các lớp RBAC khác:

public function getAllRoles($addSpecial=false)
{
	return $this->authoriser->getAllRoles($addSpecial);
}
	public function getTranslatedRole($role)
{
	return $this->authoriser->getTranslatedRole($role);
}

Một lần nữa, chúng được cung cấp để đơn giản hóa sự phát triển của mã trong tương lai để các chi tiết triển khai được tập trung ở các vị trí dễ nhận biết. Ý tưởng chung về getAllRoles là rõ ràng từ tên và tham số xác định xem các vai trò đặc biệt như khách truy cập, đã đăng ký và sẽ không có ai được đưa vào. Vì các vai trò đó được tích hợp vào hệ thống bằng tiếng Anh, sẽ rất hữu ích khi có thể có được các bản dịch địa phương cho chúng. Vì vậy, phương thức getTranslatedRole sẽ trả về một bản dịch cho bất kỳ vai trò đặc biệt nào; đối với các vai trò khác, nó sẽ trả về tham số không thay đổi, vì các vai trò được tạo động dưới dạng chuỗi văn bản và do đó thường sẽ có ngôn ngữ địa phương ngay từ đầu. Bây giờ chúng tôi đã sẵn sàng để xem xét phương pháp nhuần nhuyễn đầu tiên:

public function permittedRoles ($action, $subject_type, $subject_id)
{
	$nonspecific = true;
	foreach ($this->permissionHolders ($subject_type, $subject_id)
	as $possible)
{
	if ('*' == $possible->action OR $action == $possible->action)
{
	$result[$possible->role] = $this->getTranslatedRole
	($possible->role);
	if ('*' != $possible->subject_type AND '*' !=
	$possible_subject_id) $nonspecific = false;
	}
}
if (!isset($result))
{
	if ($nonspecific) $result = array('Visitor' =>
	$this->getTranslatedRole('Visitor'));
	else return array();
}
return $result;
}
private function &permissionHolders ($subject_type, $subject_id)
{
	$sql = "SELECT DISTINCT role, action, control, subject_type,
	subject_id FROM #__permissions";
	if ($subject_type != '*') $where[] =
	"(subject_type='$subject_type' OR subject_type='*')";
	if ($subject_id != '*') $where[] = "(subject_id='$subject_id' OR
	subject_id='*')";
	if (isset($where)) $sql .= " WHERE ".implode(' AND ', $where);
	return $this->database->doSQLget($sql);
}

Bất kỳ mã nào đang cung cấp chức năng quản trị RBAC cho một số phần của CMS có thể muốn biết vai trò nào đã có sự cho phép cụ thể để hiển thị điều này cho quản trị viên để chuẩn bị cho bất kỳ thay đổi nào. Các quyền của phương thức privateHolders sử dụng các tham số để tạo một câu lệnh SQL sẽ thu được các mục cấp phép tối thiểu có liên quan. Điều này phức tạp bởi thực tế là trong hầu hết các bối cảnh, dấu hoa thị có thể được sử dụng như một thẻ hoang dã.

Phương thức công khai allowRoles sử dụng phương thức riêng để lấy các hàng cơ sở dữ liệu có liên quan từ bảng quyền. Chúng được kiểm tra dựa vào tham số hành động để xem cái nào trong số chúng có liên quan. Nếu không có kết quả hoặc nếu không có kết quả nào đề cập cụ thể đến chủ đề, mà không sử dụng thẻ hoang dã, thì có thể giả định rằng tất cả khách truy cập có thể truy cập chủ đề, vì vậy vai trò đặc biệt của khách truy cập được thêm vào kết quả. Khi được phép thực tế, chúng tôi cần các phương pháp sau:

public function permit ($role, $control, $action, $subject_type, $subject_id)
{
	$sql = $this->permitSQL($role, $control, $action, $subject_type,
	$subject_id);
	$this->doSQL($sql, true);
}
private function permitSQL ($role, $control, $action, $subject_type, $subject_id)
{
	$this->database->setQuery("SELECT id FROM #__permissions WHERE
	role='$role' AND action='$action' AND
	subject_type='$subject_type' AND
	subject_id='$subject_id'");
	$id = $this->database->loadResult();
	if ($id) return "UPDATE #__permissions SET control=$control WHERE id=$id";
	else return "INSERT INTO #__permissions (role, control, action,
	subject_type, subject_id) VALUES ('$role', '$control',
	'$action', '$subject_type', '$subject_id')";
}

Phương pháp công cộng cho phép cấp phép cho một vai trò. Các bit điều khiển được đặt trong tham số $ control. Hành động là một phần của sự cho phép và chủ thể của hành động được xác định bởi loại chủ đề và tham số nhận dạng. Hầu hết các công việc được thực hiện bằng phương thức riêng tạo ra SQL; nó được giữ riêng biệt để nó có thể được sử dụng bởi các phương pháp khác. Khi SQL được lấy, nó có thể được chuyển đến cơ sở dữ liệu và vì thông thường nó sẽ dẫn đến thay đổi, nên tùy chọn xóa bộ đệm được đặt.

SQL được tạo tùy thuộc vào việc đã có quyền với cùng tham số chưa, trong trường hợp đó chỉ có các bit điều khiển được cập nhật. Nếu không, một chèn chèn xảy ra. Lý do phải thực hiện CHỌN đầu tiên, sau đó quyết định CHỌN hoặc CẬP NHẬT là chỉ mục trên các trường có liên quan không được đảm bảo là duy nhất và cũng vì ID chủ đề được phép dài hơn nhiều so với có thể được đưa vào trong một chỉ số. Do đó, không thể sử dụng CẬP NHẬT KHÓA NGAY LẬP TỨC.

Bất cứ nơi nào có thể, nó hỗ trợ hiệu quả để sử dụng tùy chọn MySQL để CẬP NHẬT KHÓA NGAY LẬP TỨC. Điều này được thêm vào cuối câu lệnh INSERT và nếu INSERT không thành công do khóa đã tồn tại trong bảng, thì các hành động thay thế tuân theo CẬP NHẬT KHÓA KHAI THÁC được thực hiện. Chúng bao gồm một hoặc nhiều bài tập, được phân tách bằng dấu phẩy, giống như trong câu lệnh CẬP NHẬT. Không được phép WHERE vì điều kiện cho các bài tập đã được xác định bởi tình huống khóa trùng lặp.

Một phương pháp đơn giản cho phép xóa tất cả các quyền cho một hành động và chủ đề cụ thể:

public function dropPermissions ($action, $subject_type, $subject_id)
{
	$sql = "DELETE FROM #__permissions WHERE action='$action' AND
	subject_type='$subject_type'AND subject_id='$subject_id'
	AND system=0";
	$this->doSQL($sql, true);
}

Nhóm phương thức cuối cùng liên quan đến việc gán các hàm truy cập cho các vai trò. Hai trong số chúng phản ánh nhu cầu rõ ràng là có thể loại bỏ tất cả các vai trò khỏi một người truy cập (có thể là chuẩn bị để giao vai trò mới) và việc trao một vai trò cho người truy cập. Trong trường hợp cần thiết là chỉ định một tập hợp các vai trò, tốt hơn là có một phương thức đặc biệt cho mục đích này. Một phần điều này là thuận tiện, nhưng nó cũng cung cấp một hoạt động bổ sung, giảm thiểu tập hợp các vai trò. Phương pháp là:

public function assign ($role, $access_type, $access_id, $clear=true)
{
	if ($this->handler->barredRole($role)) return false;
	$this->database->setQuery("SELECT id FROM #__assignments WHERE
	role='$role' AND access_type='$access_type' AND
	access_id='$access_id'");
	if ($this->database->loadResult()) return true;
	$sql = "INSERT INTO #__assignments (role, access_type, access_id)
	VALUES ('$role', '$access_type', '$access_id')";
	$this->doSQL($sql, $clear);
	return true;
}
public function assignRoleSet ($roleset, $access_type, $access_id)
{
	$this->dropAccess ($access_type, $access_id);
	$roleset = $this->authoriser->minimizeRoleSet($roleset);
	foreach ($roleset as $role) $this->assign ($role, $access_type,
	$access_id, false);
	$this->clearCache();
}
public function dropAccess ($access_type, $access_id)
{
	$sql = "DELETE FROM #__assignments WHERE
	access_type='$access_type' AND access_id='$access_id'";
	$this->doSQL($sql, true);
}

Phương thức gán liên kết một vai trò với một người truy cập. Nó kiểm tra các vai trò bị cấm đầu tiên, đây đơn giản là các vai trò đặc biệt được thảo luận trước đó, không thể phân bổ cho bất kỳ người truy cập nào. Như với phương thức allowQuery, không thể sử dụng BẬT CẬP NHẬT KHÓA NGAY LẬP TỨC vì toàn bộ chiều dài của ID người truy cập không phải là một phần của chỉ mục, do đó, một lần nữa sự tồn tại của một bài tập được kiểm tra. Nếu sự phân công vai trò đã có trong cơ sở dữ liệu, không có gì để làm. Nếu không, một hàng được chèn và bộ nhớ cache sẽ bị xóa.

Loại bỏ tất cả các nhiệm vụ vai trò cho một người truy cập là việc xóa cơ sở dữ liệu đơn giản và được thực hiện trong phương thức dropAccess. Phương thức cấp cao hơn gánRoleSet sử dụng dropAccess để xóa mọi bài tập hiện có. Cuộc gọi đến đối tượng ủy quyền để giảm thiểu tập hợp vai trò phản ánh việc thực hiện mô hình phân cấp. Một khi có một hệ thống phân cấp, một vai trò có thể ám chỉ một vai trò khác là bác sĩ ngụ ý bác sĩ trong ví dụ trước của chúng tôi. Điều này có nghĩa là một bộ vai trò có thể chứa dự phòng. Ví dụ, một người đã được phân bổ vai trò của nhà tư vấn không cần phải được phân bổ vai trò của bác sĩ. Phương thức minimRoleSet loại bỏ mọi vai trò cực kỳ nguy hiểm. Khi điều đó đã được thực hiện, mỗi vai trò được xử lý bằng cách sử dụng phương thức gán, với việc xóa bộ nhớ cache được lưu cho đến khi kết thúc.

Bộ đệm RBAC chung

Như đã nêu trước đó, thông tin cần thiết để giải quyết các câu hỏi RBAC được lưu trữ theo hai cách. Bộ đệm của hệ thống được xử lý bởi lớp đơn aliroAuthoriserCache, kế thừa từ lớp CacheedSingleton và được mô tả đầy đủ trong Chương 8, trên bộ đệm. Điều này có nghĩa là dữ liệu của đối tượng singleton sẽ được lưu trữ tự động trong hệ thống bất cứ khi nào có thể, với các quy định thông thường để hết thời gian bộ đệm cũ hoặc xóa bộ đệm khi cập nhật xảy ra. Rất mong muốn lưu trữ dữ liệu cả hai để tránh các hoạt động cơ sở dữ liệu và tránh lặp lại quá trình xử lý cần thiết trong hàm tạo. Vì vậy, ý định là phương thức constructor sẽ chỉ chạy không thường xuyên. Nó chứa mã này:

protected function __construct()
{
	// Making private enforces singleton
	$database = aliroCoreDatabase::getInstance();
	$database->setQuery("SELECT role, implied FROM #__role_link UNION
	SELECT DISTINCT role, role AS implied FROM
	#__assignments UNION SELECT DISTINCT role,
	role AS implied FROM #__permissions");
	$links = $database->loadObjectList();
	if ($links) foreach ($links as $link)
	{
		$this->all_roles[$link->role] = $link->role;
		$this->linked_roles[$link->role][$link->implied] = 1;
		foreach ($this->linked_roles as $role=>$impliedarray)
		{
			foreach ($impliedarray as $implied=>$marker)
			{
				if ($implied == $link->role OR $implied == $link->implied)
				{
					$this->linked_roles[$role][$link->implied] = 1;
						if (isset($this->linked_roles[$link->implied])) foreach
							($this->linked_roles[$link->implied] as $more=>$marker)
				{
			$this->linked_roles[$role][$more] = 1;
		}
	}
}
}
}
	$database->setQuery("SELECT role, access_id FROM #__assignments
	WHERE access_type = 'aUser' AND (access_id = '*'
	OR access_id = '0')");
	$user_roles = $database->loadObjectList();
	if ($user_roles) foreach ($user_roles as $role) $this-
	>user_roles[$role->access_id][$role->role] = 1;
	if (!isset($this->user_roles['0'])) $this->user_roles['0']
	= array();
	if (isset($this->user_roles['*'])) $this->user_roles['0'] =
	array_merge($this->user_roles['0'], $this->user_roles['*']);
}

Tất cả các vai trò có thể được bắt nguồn từ một UNION của các lựa chọn từ các quyền, bài tập và các bảng cơ sở dữ liệu vai trò được liên kết. Hoạt động liên minh có tổng phí, do đó, một mình là một lý do để ưu tiên sử dụng bộ đệm. Việc xử lý các vai trò được liên kết cũng rất phức tạp và do đó đáng để chạy thường xuyên nhất có thể. Thay vì làm việc thông qua mã một cách chi tiết, sẽ hữu ích hơn khi mô tả những gì nó đang làm. Khái niệm đơn giản hơn nhiều so với chi tiết! Nếu chúng ta lấy một ví dụ từ các tính năng tương thích ngược của Aliro, có một hệ thống phân cấp vai trò bao gồm Nhà xuất bản vai trò, ngụ ý là thành viên của Trình chỉnh sửa vai trò. Trình chỉnh sửa vai trò cũng ngụ ý thành viên của vai trò Tác giả. Trong trường hợp chung, thật không hợp lý khi mong đợi người quản trị tìm ra các mối quan hệ ngụ ý. Trong trường hợp này, rõ ràng là Nhà xuất bản vai trò cũng phải bao hàm tư cách thành viên của Trình chỉnh sửa vai trò. Nhưng những mối quan hệ liên kết này có thể trở nên khá phức tạp. Do đó, mã trong hàm tạo giả định rằng chỉ có số lượng kết nối ít nhất được nhập vào cơ sở dữ liệu và nó tìm ra tất cả các hàm ý.

Hoạt động khác trong đó mã không trong suốt là cài đặt thuộc tính user_roles. Hệ thống Aliro RBAC cho phép sử dụng thẻ hoang dã để xác định danh tính cụ thể trong bộ truy cập hoặc loại chủ đề. Một dấu hoa thị cho thấy bất kỳ danh tính. Đối với những người truy cập có loại người truy cập là người dùng, một thẻ hoang dã khác có sẵn bằng không. Điều này có nghĩa là bất kỳ người dùng nào đã đăng nhập và không phải là khách truy cập chưa đăng ký. Với số lượng vai trò tương đối nhỏ của loại này, nó sẽ tiết kiệm rất nhiều xử lý nếu tất cả chúng được lưu trữ. Do đó việc xử lý user_roles được thực hiện trong hàm tạo.

Các phương thức khác trong lớp bộ đệm đủ đơn giản để được đề cập thay vì được đưa ra chi tiết. Chúng bao gồm việc triển khai thực tế phương thức getTranslatedRole, cung cấp các bản dịch cục bộ cho các vai trò đặc biệt. Các triển khai thực tế khác là getAllRoles với tùy chọn bao gồm các vai trò đặc biệt, getTranslatedRole, dịch một vai trò nếu nó trở thành một trong những vai trò đặc biệt và barredRole, lần lượt kiểm tra xem vai trò đã qua có thuộc nhóm đặc biệt không . Do đó, nó có thể không được chỉ định cho một người truy cập.

Đặt câu hỏi RBAC

Có lẽ lớp không thể tin được nhất là lớp thực sự trả lời các câu hỏi về quyền truy cập được phép. Lớp aliroAuthoriser một lần nữa là một singleton với các cơ chế thông thường. Để thuận tiện, nó có các phương thức getAllRoles và getTranslatedRole, nhưng chúng thực sự được triển khai trong lớp bộ đệm được mô tả ở trên.

Hàm tạo thực hiện một số cài đặt tương đối đơn giản, bao gồm tìm kiếm dữ liệu được lưu trong bộ nhớ cache trong siêu toàn cầu $ _SESSION:

private function __construct()
{
	// Make sure session started
	aliroSessionFactory::getSession();
	// Use session data as the source for cached user related data
	foreach ($this->auth_vars as $one_var)
	{
		if (!isset($_SESSION['aliro_auth'][$one_var]))
		$_SESSION['aliro_auth'][$one_var] = array();
		$this->$one_var =& $_SESSION['aliro_auth'][$one_var];
	}
	$this->handler = aliroAuthoriserCache::getInstance();
	$this->linked_roles = $this->handler->getLinkedRoles();
	$this->database = aliroCoreDatabase::getInstance();
}

Nhận phiên hiện tại, mặc dù nó không được sử dụng trực tiếp cho bất cứ điều gì, đảm bảo rằng phiên đã được bắt đầu để $ _SESSION sẽ chứa dữ liệu, nếu có. Vì Aliro luôn kích hoạt một phiên và nhiều dữ liệu RBAC được chỉ định cho người dùng hiện tại, nên có ý nghĩa tốt khi lưu trữ dưới dạng dữ liệu phiên. Các đối tượng xử lý và cơ sở dữ liệu được tìm thấy bằng cách sử dụng phương thức truy cập singleton thông thường, getInstance và các vai trò được liên kết được lấy từ bộ đệm của người ủy quyền.

Nhiều câu hỏi RBAC liên quan đến vai trò và tùy chọn phân cấp có nghĩa là một vai trò có thể ám chỉ một vai trò khác. Mối quan hệ này được lưu trữ trong thuộc tính Linked_roles. Có vai trò ngụ ý có nghĩa là một tập hợp vai trò có thể bao gồm các mục không thực sự cần thiết. Phương thức minimRoleSet loại bỏ chúng:

public function minimizeRoleSet ($roleset)
{
	if (0 == count($roleset)) return $roleset;
	$first = array_shift($roleset);
	foreach ($roleset as $key=>$role)
	{
		if (isset($this->linked_roles[$first][$role])) unset
		($roleset[$key]);
		if (isset($this->linked_roles[$role][$first])) return
		$this->minimizeRoleSet ($roleset);
	}
	array_unshift($roleset, $first);
	return $roleset;
}

Có khoảng một số phương pháp khác, một số công khai và một số riêng tư. Về chi tiết, những cái chính trở nên khá phức tạp. Điều này một phần là do bản chất của RBAC, và một phần là do những nỗ lực với hiệu quả. Những người khác rất đơn giản, nhưng điều này là do chúng là các giao diện cho các phương thức quan trọng hơn, nhưng với các tham số ed đơn giản, để cung cấp một giao diện dễ sử dụng hơn. Do tính phức tạp, một lựa chọn của các lớp còn lại được thảo luận trong đề cương thay vì được xem xét chi tiết. Mã đầy đủ có thể tải xuống từ trang web Aliro.

Quyền đề cập đến các hành động về các chủ đề và rất có khả năng nhiều truy vấn sẽ phát sinh xung quanh các chủ đề tương tự. Phương thức riêng getSubjectData được sử dụng để tải các quyền, dựa trên một chủ đề và một hành động, nghĩa là, một quyền cụ thể cụ thể. Phương pháp này luôn đảm bảo rằng tất cả các hàng có liên quan từ bảng quyền sẽ được tải. Số lượng các hàng có liên quan trực tiếp sẽ là số lượng vai trò có sự cho phép. Nhưng phương pháp cũng cố gắng để có được nhiều dữ liệu hơn là rất cần thiết. Tùy thuộc vào số lượng hồ sơ liên quan, phương pháp có thể tải tất cả dữ liệu cấp phép liên quan đến loại chủ đề specifi ed, không chỉ đối với chủ đề cụ thể. Số chính xác được chọn là tùy thuộc vào công việc tối ưu hóa. Điều đó có nghĩa là, tất cả các bản ghi trong đó loại chủ đề khớp, không chỉ những bản ghi phù hợp với cả hai loại chủ đề, và chủ đề nhận dạng er. Điều này được thực hiện bởi vì thông thường đối với một câu hỏi về quyền đối với một chủ đề cụ thể thường được theo sau bởi một câu hỏi về một chủ đề khác cùng loại. Dữ liệu cấp phép được tải được tổ chức thành các cấu trúc mảng để tối đa hóa hiệu quả của việc tra cứu và nó cũng được lưu trong bộ nhớ cache dưới dạng dữ liệu phiên.

Phương thức getAccessorRoles được sử dụng cả bên trong và bên ngoài. Nguyên mẫu của nó là:

public function getAccessorRoles ($type, $id)

Nó cũng trả về một loạt các vai trò. Việc xử lý rất phức tạp bởi việc lưu trữ dữ liệu trong bộ đệm, một điều đặc biệt quan trọng đối với người truy cập vì rất có thể một số câu hỏi sẽ được hỏi về người dùng hiện tại. Các tham số là loại trình truy cập (chẳng hạn như 'Người dùng') và nhận dạng er (chẳng hạn như số ID người dùng).

Một phương thức riêng, accessorPermissionOrControl, thực hiện công việc cơ bản để tìm hiểu xem một người truy cập cụ thể có quyền đối với một chủ đề nhất định cho một hành động đã nêu hay không. Các loại truy cập được thông qua như một mặt nạ bit. Phương pháp này sau đó được sử dụng để tạo ra một loạt các phương thức công khai rất đơn giản. Việc sử dụng thường xuyên nhất có một nguyên mẫu:

public function checkPermission ($a_type, $a_id, $action, $s_type='*', $s_id='*')

Kết quả bằng 0 hoặc một để chỉ ra sai hoặc đúng tương ứng. Kiểu người truy cập và ID cùng với người truy cập. Hành động là tự giải thích. Loại chủ đề và ID cùng xác định chủ đề. Có những tình huống sử dụng thẻ hoang dã. Ví dụ: khi hành động là để quản lý và chủ thể là tất cả người dùng, thì ID chủ đề sẽ là thẻ đại diện dấu hoa thị. Các hành động khác có thể không có chủ đề nào cả, trong trường hợp đó cả loại chủ đề và ID sẽ là dấu hoa thị.

Để dễ phát triển, một phương án thay thế cho checkPermission là phương pháp với nguyên mẫu:

public function checkUserPermission ($action, $s_type='*', $s_id='*')

Nó giả định rằng người truy cập là người dùng hiện tại, người có thể lấy thông tin chi tiết từ một lớp tiêu chuẩn trong CMS, vì vậy chỉ có hành động và chủ đề cần được xác định cụ thể. Các phương pháp tương tự với hai phương thức cuối cùng cũng tồn tại để xử lý việc cấp quyền.

Mặc dù liên kết giữa người truy cập và chủ thể thông qua vai trò thường có thể được giữ dưới vỏ bọc và được xử lý trong lớp ủy quyền, trong một số trường hợp cần phải rõ ràng. Do đó, có thể hỏi liệu một vai trò cụ thể có thể truy cập một chủ đề cho một hành động cụ thể không:

public function checkRolePermission ($role, $action, $s_type, $s_id)

Khi quyết định các câu hỏi về quyền truy cập vào các đối tượng thường được quản lý bởi một phần mềm khác, truy vấn hiệu quả nhất là tìm ra mục nào không khả dụng. Hãy trở lại ví dụ của chúng tôi về kho lưu trữ, trong đó các vai trò được cấp quyền truy cập để tải xuống từ các thư mục cụ thể. Một thư mục được nhận dạng theo loại chủ đề của nó, giả sử remosFolder và nhận dạng er, trong trường hợp này là số ID. Bởi vì chúng tôi có một quy tắc nói rằng bất cứ điều gì không có bất kỳ quyền hạn cụ thể nào đều có sẵn cho tất cả, nên có thể xác định danh sách tất cả các thư mục có quyền của một số loại. Đối với một số người, người dùng mà chúng tôi đang hỏi có thể đã được cấp quyền truy cập, thông qua vai trò của họ. Vì vậy, các thư mục được loại bỏ khỏi danh sách. Nếu bất kỳ thư mục nào còn lại, chúng là những nơi không cho phép truy cập.

public function getRefusedList ($a_type, $a_id, $s_type, $actionlist)

Nó trả về một mảng các số ID, được cung cấp bởi một người truy cập được xác định theo loại và ID cùng với một loại chủ đề và một danh sách hành động. Danh sách hành động có thể là một hành động đơn lẻ, nhưng để thuận tiện, nó được phép là danh sách hành động được phân tách bằng dấu phẩy. Kết quả là số ID cho tất cả các thư mục mà người truy cập bị từ chối cấp phép để thực hiện bất kỳ hành động nào.

Một lần nữa để cung cấp giao diện hữu ích hơn, phiên bản mở rộng của phương thức có sẵn:

public function getRefusedListSQL ($a_type, $a_id, $s_type, $actionlist, $keyname)

Nó trả về một đoạn SQL. Lấy một ví dụ, nếu chúng ta gọi getRefuseListQuery ('aUser', 47, 'remosFolder', 'download', 'id'), chúng ta có thể lấy lại một chuỗi chứa CAST (id AS CHAR) KHÔNG IN ('5', '14' , '27'). Điều này có thể được sử dụng như một phần của câu lệnh SQL để chọn các thư mục mà người dùng có ID 47 được phép tải xuống. Vì vậy, giả sử chúng tôi muốn có một danh sách các tên của bộ chứa kho lưu trữ có sẵn cho người dùng mẫu của chúng tôi, SQL đầy đủ sẽ được xây dựng bằng cách sử dụng tên CHỌN TỪ #__doads_containers WHERE theo sau là một phần SQL được cung cấp bởi getRefuseListQuery. SQL mẫu cuối cùng sau đó là tên CHỌN TỪ #__ download_containers WHERE CAST (id AS CHAR) KHÔNG IN ('5', '14', '27').

Tóm lược

Bây giờ chúng ta đã có ít nhất là phác thảo của một hệ thống kiểm soát truy cập dựa trên vai trò rất khả thi. Các nguyên tắc được thiết lập, sử dụng các khái niệm tiêu chuẩn của RBAC. Thông tin chi tiết cụ thể, chẳng hạn như cách người truy cập và đối tượng được nhận dạng ed phù hợp với tình huống cụ thể của khung CMS.

Việc thực hiện trong cơ sở dữ liệu đã được thiết lập chi tiết. Chúng tôi đã nghiên cứu mã để quản lý RBAC và xem xét phác thảo cách các câu hỏi về quyền truy cập có thể được trả lời. Thông tin chi tiết có sẵn bằng cách tải về triển khai Aliro.

Bài viết này được trích từ cuốn sách PHP5 CMS Framework Development, của Martin Brampton, và được xuất bản vào ngày 6 tháng 6 năm 2008 bởi Packt Publications.

Mua cuốn sách này ở đâu

Bạn có thể mua PHP5 CMS Framework Development từ Amazon

|