多租户(multi-tenancy)是一種軟件架構技術,是實現在多租户的環境下共用相同的系統或程序組件,並且保證各用户間的數據隔離,也可稱作域租户。
PHP-Casbin 不僅提供了全局的RBAC的權限模型,而且還支持特定域的權限模型。特定租户/域的角色意味着當用户在不同的租户/域中時,用户可以擁有不同的角色,亦擁有不同的權限策略。在大型項目中,特別是在像SaaS PaaS這種雲服務中,不同的租户需要擁有獨立的權限控制,這就非常有用。
用例
這裏我以一個多商户的電商平台為例,電商平台的商户就是租户,每個商户有自己的管理人員,可以分配不同的角色,定義自己的權限。這些商户間的數據在邏輯上是完全隔離的,但他們共享這個電商平台的其他資源。
多商户電商平台
商户1,用户1,屬於管理員角色
商品1
商户2,用户2,屬於管理員角色
商品2
如上述,在這個電商平台下,每個商户就是一個租户,在每個商户下面有用户和商品。這些用户和商品是相互隔離的,並且在每個商户下面都有一套獨立的權限控制系統。
模型
在官方倉庫中提供了多租户的模型配置,rbac_with_domains_model.conf:
[request_definition]
r = sub, dom, obj, act
[policy_definition]
p = sub, dom, obj, act
[role_definition]
g = _, _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act
通過上面的模型配置,可以看出,相比普通的RBAC模型,它多了一個dom參數,這個dom就是上文所説的商户(domain)。
在[role_definition]中g = _, _, _,有三個佔位符,分別代表:用户、角色、租户/域。
在[matchers]中的g(r.sub, p.sub, r.dom)就是判斷用户、角色和租户/域之間的關係。
策略
根據上面的用例要求,下面分別定義了商户1(tenant1)和商户2(tenant2)的管理員權限策略,並且在各自的租户下賦予了user1和user2的管理員(admin)角色。
p, admin, tenant1, goods1, read
p, admin, tenant1, goods1, write
p, admin, tenant2, goods2, read
p, admin, tenant2, goods2, write
g, user1, admin, tenant1
g, user2, admin, tenant2
上面的策略配置在rbac_with_domains_policy.csv文件中。
決策
如果你的項目還有沒有引入Casbin依賴,則需要安裝一下,通過composer require casbin/casbin。
這是演示的是純原生PHP代碼,先初始化一個決策器Enforcer。如果是在Laravel、ThinkPHP、Yii等主流框架中,可以直接使用對應的擴展,拿到決策器的Facade即可。
<?php
require_once './vender/autoload.php';
use Casbin\Enforcer;
$enforcer = new Enforcer('path/to/rbac_with_domains_model.conf', 'path/to/rbac_with_domains_policy.csv');
上面實例化了一個決策器(Enforcer),首先,來驗證一下商户1下用户的權限:
var_dump(
$enforcer->enforce('user1', 'tenant1', 'goods1', 'read'), // true
$enforcer->enforce('user1', 'tenant1', 'goods1', 'write'), // true
$enforcer->enforce('user1', 'tenant2', 'goods2', 'read'), // false
$enforcer->enforce('user1', 'tenant2', 'goods2', 'write'), // false
);
可以看出,在商户1 下,用户1 對商品1 擁有read和write的,但他對商户2 下的商品是沒有權限的。
同樣,下面驗證商户2 的權限,在商户2 下,用户2 對商品2 有權限,而對商户1 是沒有權限的。
var_dump(
$enforcer->enforce('user2', 'tenant1', 'goods1', 'read'), // false
$enforcer->enforce('user2', 'tenant1', 'goods1', 'write'), // false
$enforcer->enforce('user2', 'tenant2', 'goods2', 'read'), // true
$enforcer->enforce('user2', 'tenant2', 'goods2', 'write'), // true
);
最後
假設你正在開發一個面向企業的SaaS雲服務平台,多租户權限控制的設計一定是必不可少。多租户實現了多個租户共享相同的資源和組件,租户之間的數據隔離,具有很高的成本效益,具有很大的靈活性和可擴展性。通過PHP-Casbin就可以快速的實現的多租户權限控制模型的設計和開發。