Casbin在Web中的實例

最近的項目需要設計一個比較複雜的權限系統,用到了casbin,簡單做個使用說明。

1. 設計理念

casbin是一套權限控制框架,支持多種經典的訪問控制模型(ACL、RBAC等)。casbin通過PERM (Policy, Effect, Request, Matcher) 四類配置,即可組合出各種複雜權限模型。

  • Policy: 定義權限的規則
  • Effect: 定義當命中多個 Policy 之後的結果, allow or deny
  • Request: 定義訪問請求,
  • Matcher: 判斷 Request 是否滿足 Policy

2. RBAC demo

通過官網上的一個RBAC的例子來理解上述內容。一般有兩個文件來定義model.conf和rbac_policy.csv。

首先在model.conf文件中定義casbin的基本規則。

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
  • [request_definition]定義Request格式:sub(用戶或角色),obj(某個資源,比如url),act(訪問的動作,比如GET)
  • [policy_definition]定義Policy的格式規則,也是sub,obj,act,即插入的policy規則需要滿足sub,obj,act的要求
  • [role_definition]定義Group,當使用RBAC時,用戶所屬的角色可以通過此來定義,常見有兩種:
    • g = , 表示用戶、角色
    • g = ,,_ 表示用戶、角色、域
  • [policy_effect]定義Policy生效規則,e = some(where (p.eft == allow)表示任意一條policy rule命中即生效;
  • [matchers]定義匹配request 和 policy 的方式。

其次是rbac_policy.csv,具體保存Policy和group規則。

p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write

g, alice, data2_admin

官網這個例子很簡單,

  • p, alice, data1, read表示添加的是一條Policy,Alice用戶可以read data1
  • p, data2_admin, data2, read表示角色data2_admin可以read data2
  • g, alice, data2_admin表示alice的角色爲data2_admin

以上都是配置文件,完成配置後,具體使用時

import casbin
e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")

sub = "alice"  # the user that wants to access a resource.
obj = "data1"  # the resource that is going to be accessed.
act = "read"  # the operation that the user performs on the resource.

if e.enforce(sub, obj, act):
    # permit alice to read data1
    pass
else:
    # deny the request, show an error
    pass

3. RBAC in Web

官網這個例子比較基本,再舉一個更常見的例子,如何casbin應用在Web server中。可以將路由route作爲obj,請求方式Method作爲act,登錄用戶的角色作爲sub,在每一次請求時,把這3個參數傳遞給e.Enforce,即可判斷。

model_conf:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

policy.csv

p, admin, /hello, GET

g, guoxingyu, admin

app.py

import casbin
from flask import Flask, request, abort


app = Flask(__name__)
e = casbin.Enforcer("./conf/model.conf", "./conf/policy.csv")


@app.route('/hello', methods=['GET'])
def hello():
    return '<h1>hello world</h1>'


@app.before_request
def check_request():
    name = request.args.get('username')
    url = request.path
    act = request.method
    if not e.enforce(name, url, act):
        return abort(401)


@app.errorhandler(401)
def error(arg):
    return "用戶沒權限"

效果

當參數username是guoxingyu時,請求成功


當參數username是other時,請求失敗


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章