Phân quyền là một tính năng xuất hiện ở rất nhiều nơi trong ứng dụng phần mềm. Đơn cử như việc chia sẻ tệp tin trên internet cho nhau, bạn có thể cho người nhận quyền đọc, tải về hoặc chỉnh sửa nội dung... Còn trong các ứng dụng quản lý hệ thống như CMS, phân quyền trở nên cần thiết hơn bao giờ hết. Mỗi người dùng chỉ nên có quyền truy cập vào tài nguyên được phép để tránh gặp phải những rắc rối sau này.
Trước đây khi làm phân quyền, cách đơn giản nhất là sử dụng if...else
để kiểm tra một thuộc tính nào đó, ví dụ như là role
của người dùng có hợp lệ khi thao tác với tài nguyên. Ví dụ, người dùng có role
là admin
sẽ có quyền tối cao trong hệ thống, trong khi mod
thì có quyền thấp hơn. Hai hàm checkAdmin
và checkMod
được tạo ra để kiểm tra nhanh xem người dùng có đang là admin
hay là mod
, chúng được gọi khi cần kiểm tra quyền trước khi đụng đến logic xử lý tài nguyên.
function checkAdmin(role) {
if (role === "admin") {
return true;
}
return false;
}
function checkMod(role) {
if (role === "mod") {
return true;
}
return false;
}
Đó chỉ phù hợp cho các ứng dụng đơn giản mà không đòi hỏi phân quyền nghiêm ngặt. Thực tế thì đôi khi ứng dụng của chúng ta cần quản lý chặt chẽ hơn, ví dụ như một nhóm người dùng là mod
có quyền đọc/ghi vào dữ liệu ở các API nhất định. Đôi khi chúng ta còn phải xây dựng một trang quản lý quyền của người dùng, đó mà một màn hình chi chít thiết lập dành cho người dùng, hành động và cả tài nguyên được phép truy cập.
Tôi tin rằng có rất nhiều cách để triển khai phân quyền và nó đi theo từng trường hợp cụ thể của mỗi hệ thống. Vì thế bài toán bảo trì mới cần được bàn đến. Nếu như việc triển khai phân quyền từ đầu không tốt hoặc gây khó khăn trong đọc hiểu, mở rộng thì cần mất nhiều thời gian hơn nếu muốn sửa đổi, nâng cấp. Ngược lại, khi chúng ta có một tiếng nói chung thì khả năng tiếp cận vấn đề lại nhanh hơn đáng kể.
Casbin là một thư viện kiểm soát truy cập mã nguồn mở, nó cung cấp khả năng hỗ trợ cho việc thực thi ủy quyền dựa trên các mô hình kiểm soát truy cập khác nhau. Các mô hình phân quyền phổ biến được Casbin hỗ trợ và triển khai trong nhiều ngôn ngữ lập trình khác nhau. Nói cách khác, nó chỉ đơn giản hóa việc viết mã của bạn cho vấn đề phân quyền.
Có khá nhiều cách để kiểm soát quyền truy cập, chưa kể đến sự tùy biến của chúng để phù hợp cho nhiều bài toán của mỗi ứng dụng. Nhưng nhìn chung, chúng ta có 3 cách phổ biến là ACL, RBAC và ABAC.
ACL là viết tắt của cụm từ Access Control List, nghĩa là người dùng được ánh xạ tới các hành động đối với tài nguyên.
Trước khi tiếp tục, có 3 khái niệm cơ bản để kiểm soát quyền truy cập đó là người dùng - hay nói một cách bao quát là đối tượng (sub), chúng ta có tài nguyên cần truy cập (obj) và hành động mà đối tượng được phép với tài nguyên (act).
Quay trở lại với ví dụ đầu tiên, mod
có quyền thêm/sửa/xóa bài viết. Bài viết lúc này là obj, hành động thêm/sửa/xóa là act và mod
chính là sub. Đây là một ví dụ điển hình cho ACL.
Phức tạp hơn một chút, chúng ta có RBAC là viết tắt của Role-Based Access Control - Kiểm soát truy cập dựa trên vai trò.
RBAC cũng khá giống ACL ở các quyền và tài nguyên được phép truy cập, nhưng thay vì gán quyền trực tiếp đến một đối tượng người dùng cuối thì nó tạo ra một đối tượng trung gian gọi là "role", người dùng có "role" nào thì sẽ có quyền của role đó.
Ví dụ mod
có quyền thêm/sửa/xóa bài viết, hoaitx
là một người dùng trong hệ thống và có "role" là mod
cho nên hoaitx
có quyền thêm/sửa/xóa bài viết...
Một mô hình phổ biến nữa là kiểm soát truy cập dựa trên thuộc tính ABAC - Attribute-Based Access Control. ABAC cũng khá tương đồng với RBAC, nhưng thay vì quản lý quyền theo "role" thì ABAC quản lý quyền theo thuộc tính (attribute). Nghĩa là đối tượng có mang thuộc tính nào thì sẽ có quyền của thuộc tính đó. Một ví dụ cho dễ liên tưởng là gắn tags, nếu người dùng hoaitx
được gắn tags read_article
và nó có quyền đọc bài viết thì hoaitx
cũng có quyền đọc bài viết...
Trước khi triển khai, chúng ta hãy dành thời gian để tìm hiểu cách hoạt động của Casbin, vì một khi đã hiểu thì có thể giúp bạn làm quen nhanh hơn với mô hình phân quyền này.
Trong Casbin, mô hình kiểm soát truy cập được trừu tượng hóa thành tệp CONF dựa trên siêu mô hình PERM. Mô hình PERM bao gồm bốn nền tảng: Policy, Effect, Request, và Matchers. Những nền tảng này mô tả mối quan hệ giữa tài nguyên và người dùng.
Để tìm hiểu chi tiết về 4 nền tảng này, bạn đọc tham khảo thêm tại How It Works - Casbin.
Các tệp CONF định nghĩa cho mô hình phân quyền ACL, RBAC, ABAC... bạn có thể tự tạo cho mình một cấu hình riêng hoặc sử dụng các mẫu có sẵn của Casbin. Ví dụ một tệp sử dụng cho ACL có dạng như sau:
# Request definition
[request_definition]
r = sub, obj, act
# Policy definition
[policy_definition]
p = sub, obj, act
# Policy effect
[policy_effect]
e = some(where (p.eft == allow))
# Matchers
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
Tiếp đến chúng ta cần một tệp định nghĩa các giá trị sub, obj, act... như đã nêu đầu bài viết, mục đích là chỉ định cho đối tượng có quyền gì với tài nguyên nào. Các tệp này được gọi là tệp policy
.
Ví dụ policy
của một ACL như sau:
p, hoaitx, article, read
p, hoaitx, article, write
Sau đó sử dụng 2 tệp tin này trong mã để kiểm tra điều kiện phân quyền. Ví dụ khi triển khai với Node.js, đầu tiên cài đặt modules casbin
:
$ npm i casbin
Sau đó sử dụng:
import { newEnforcer } from 'casbin';
const e = await newEnforcer('path/to/model.conf', 'path/to/policy.csv');
Với path/to/model.conf
là đường dẫn đến tệp CONF, path/to/policy.csv
là đường dẫn đến tệp policy
vừa tạo ra.
Sau đó để kiểm tra người dùng hoaitx
có quyền read
tài nguyên article
hay không rất đơn giản:
const sub = 'hoaitx';
const obj = 'article';
const act = 'read';
if ((await e.enforce(sub, obj, act)) === true) {
// permit
} else {
// deny
}
Đó chỉ là ví dụ cơ bản, Casbin cung cấp rất nhiều mô hình phân quyền nâng cao hơn nữa, các API mạnh mẽ khác như quản lý policy
một cách linh hoạt hoặc hỗ trợ lưu trữ, cập nhật các tệp CONF theo nhiều cách khác nhau. Bạn đọc tìm hiểu thêm tại API Overview và Model Storage hoặc bắt đầu với trang tài liệu chính thức của Casbin: Overview.
5 bài học sâu sắc
Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!
Đăng ký nhận thông báo bài viết mới
Bình luận (0)