2004-12-23

Introduction to ACL (authentication, authorization and security)

Giới thiệu ACL (Access Control Lists)

ACL là tính năng quan trọng và hay được thảo luận nhất. Không chỉ bởi đây là tính năng được mong đợi mà còn bởi vì nó là tính năng gây nhiều thắc mắc và khó hiểu nhất (the most confusing).

Như chúng ta được nghe đến trong nhiều tài liệu online, ACL là cách thức để quản lý ứng dụng thuận tiện, khoa học, chi tiết và dễ dàng maintance. ACL quản lý 2 phần của một vấn đề: một bên cần sử dụng và một bên là thứ cần sử dụng. Trong ngôn ngữ của ACL, bên cần sử dụng (thông thường là users) được gọi là Access Request Objects tức đối tượng yêu cầu truy cập viết tắt là AROs. Và những thứ trong hệ thống đang được yêu cầu sử dụng gọi là Access Control Objects đối tượng cần quản lý truy cập viết tắt là ACOs. Các thực thể trên (entities) được gọi là objects bởi đôi khi requesting objects không phải là person- đôi khi chúng ta muốn limit access tới một controllers cụ thể nào đó có nhiệm vụ khởi động logic trong một vài phần khác.

Trong CakePHP thì nó như sau:

The entities are called 'objects' because sometimes the requesting object isn't a person - sometimes you might want to limit the access certain Cake controllers have to initiate logic in other parts of your application.

ACOs có thể là những thứ chúng ta muốn control, từ controller action tới web service ...

Review
ACO - Access Control Object - Something that is wanted
ARO - Access Request Object - Something that wants something

Khi đó ACL sẽ dùng để quyết định ARO nào có thể access ACO nào.

Nên nhớ rằng ACL không giống authenticate. ACL có thể xảy ra sau khi user đã authenticated. Mặc dù ACL thường dùng chung với authentication nhưng quan trọng chúng ta cần phân biệt rõ 2 vấn đề ai (authentication) và người đó được làm cái gì (ACL). Tức là sau khi tiếp cận được (authenticated) thì mới đến bước cấp quyền (authority). Ví dụ được vào nhà nhưng không được làm gì khác với không được phép vào nhà.

Theo truyền thống, hệ thống sẽ quản lý sử dụng một matrix, matrix này bao gồm danh sách các users và permissions liên quan tới các object. Thông tin như vậy chúng ta sẽ thực hiện lưu trữ trong một table (table cũng là một dạng matrix).

Nhìn thoáng qua thì system theo dạng này có vẻ work well: nhìn rất fine-grained (mịn, chi tiết) và dễ đọc.

Chúng ta sẽ đi thẳng vào ví dụ cụ thể như sau: giả sử có một site về game. Chúng ta có các class trong game (dựa theo game Granado Espada đang chơi) như sau: fighter chiến binh, musketeer ngự lâm, scout trinh sát, elementalist phù thủy, wizard pháp sư.

Các vũ khí có được bao gồm sword kiếm, dagger dao găm, pistol súng ngắn, rifle súng trường, staff gậy phép và bracelet vòng tay phép (chỉ trích ra 1 số vũ khí).

Tất nhiên wizard pháp sư sử dụng gậy phép, elementalist phù thủy sử dụng vòng tay phép, scout trinh sát sử dụng dao găm, musketeer ngự lâm dùng súng các loại. Fighter rắc rối nhất có thể dùng kiếm, dao găm, và súng ngắn. Và tất nhiên là tay không tất cả đều sử dụng được.

Theo bảng matrix thông thường chúng ta sẽ hình dung như sau:

Sword
Dagger
Pistol
Rifle
Staff
Bracelet
Fighter
Allow
Allow
Allow



Musketeer


Allow
Allow


Scout

Allow




Elementalist




Allow

Wizard





Allow

Tuy nhiên mỗi loại vũ khí lại có thể chia thành từng loại nhỏ riêng biệt và có khả năng việc chia nhỏ này sẽ thực hiện trong tương lai. Trong trương lai có thể có cả những trường hợp cá biệt.

Vấn đề đặt ra là với hệ thống nhỏ matrix có thể dễ dàng setup và work nhưng khi hệ thống phát triển, số AROs và ACOs tăng lên thì table phình rất nhanh (theo cấp số nhân với mỗi chiều và còn hơn như vậy nếu cả 2 chiều cùng tăng). Hãy tưởng tượng nếu phải quản lý cả hàng trăm đối tượng theo từng unit. Điều này càng khó khăn khi thực hiện grouping permissions cho một group sections of user.

Giả sử một wizard sử dụng được tất cả các bracelet nhưng nếu chia nhỏ bracelet ra làm fire lửa, wind gió, ice băng, lightning sét thì bẳng matrix này không còn đáp ứng được. Khi đó chúng ta phải chia nhỏ thành 4 loại bracelet giống như đã chia gun thành pistolrifle.

Nếu tổ chức group và decide permissions cho một group thì việc phải giải quyết individual permissions cho user. Giả sử một fighter đặc biệt vì một lý do nào đó không thể sử dụng pistol chúng ta sẽ đáp ứng bằng cách nào trong khi vẫn đảm bảo không có gì đặc biệt thì fighter vẫn sử dụng được súng.

Tất cả những điều này làm cho việc dùng ACL dạng matrix là không hợp lý vì không thể hiện rõ những lợi điểm của group của cả AROs và ACOs.

Với các tiếp cận ACL chúng ta thấy ACL hầu hết được implemented theo cấu trúc cây. Thông tường sẽ có một cây cho AROs và một cây cho ACOs. Với cấu trúc này có thể quản lý invidual hay group như một node.

Giả sử chúng ta có hệ thống các characters (các character của tui) theo dạng tree như sau:




















Tuy nhiên có một điểm đặc biệt fighter Carol không sử dụng được pistol (bé Carol này không thích súng ). Tuy nhiên trường hợp đặc biệt như Nil thì khác, có thêm khả năng đặc biệt là dùng được rifle súng trường chẳng hạn.

Trong khi đó khi tổ chức một site về các weapons bằng một tree of ACOs sẽ như sau:




















Áp dụng mô tả trên permissions trên ta có:

























Với cách áp dụng này chúng ta có khả năng thay đổi wide-reaching permissions tuy nhiên có thể điều chỉnh một cách rất mịn fine-grained.
Với trường hợp thông thường như April với staff chúng ta có bảng ACL như sau:

ARO node
Permission info
Result
All characters
Deny all
Denying access to staff
Elementalist
Allow staff
Allowing access to staff
April
--
Still allowing staff

Như chúng ta thấy với một trường hợp đặc biệt như Carol dễ dàng nhận ra tất cả mọi fighter đều sử dụng được pistol trừ Carol. Để kiểm tra Carol với pistol ta thực hiện kiểm tra access theo path: All characters -> Fighter -> Carol, theo cách từ trên xuống như vậy thì thông tin permission liên quan tới pistol như sau:

ARO node
Permission info
Result
All characters
Deny all
Denying access to pistol
Fighter
Allow pistol
Allowing access to pistol
Carol
Deny pistol
Denying pistol