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时,请求失败


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