Skip to main content

策略库为 RBAC 策略实施提供支持。

项目描述

# Policy
策略库为 RBAC 策略实施提供支持。


## 前言

当我使用 ``Flask`` 编写``RESTful web service`` 时,我没有找到合适的扩展来处理端点的权限控制。因为我非常喜欢 OpenStack 服务基于策略文件的权限控制方法。所以我想实现一个更通用的库,类似于“oslo.policy”。


## Demo

### 生成策略文件

假设有两个角色:**user** 和 **admin**,以及两个资源:**article** 和 **user**。我们有 3 个政策:

- 只有用户可以更新文章
- 创建新用户需要管理员权限。
- 只有文章所有者或管理员角色用户可以删除文章。

根据前面的描述,我们生成以下策略文件``policy.json``:

{
"is_admin": "role:admin",
"is_user": "role:user or role:admin",

"article:update" : "rule:is_user",
"article:delete": "role:admin or id:%(user_id)s",
"user:create": "rule:is_admin"
}


### Enforce Policy With Flask Application

假设我们有一个简单的 ``Flask`` 应用程序,它提供了两个 api:创建新用户和删除文章,我们运行它:

```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import functools

从烧瓶进口烧瓶,请求,g

来自策略导入 Enforcer
from policy.exceptions import PolicyNotAuthorized

app = Flask(__name__)
enforcer = Enforcer('policy.json', raise_error=True)


@app.errorhandler(PolicyNotAuthorized)
def handle_policy_exception(error):
return str(error)


users = {
'lily' :{
'id':'d55a4192eb3b489589d5ee95dcf3af7d',
'角色':['user','admin']
},
'kate':{
'id':'1a535309687244e2aa434b25ef4bfb59',
'角色':['user']
},
'露西':{
'id':'186977181e7f4a9e85104ca017e845f3',
'角色':['用户']
}
}

文章 = {
'python': {
'id': 'e6e31ad693734b269099d9acac2cb800',
'user_id': '1a535309687244e2aa434b25ef4bfb59' # 归凯特所有
}
}


def login_required(func):
@functools.wraps(func)
def Wrapped(*args, **kwargs):
username = request.args .get('me')
credential = users.get(username)
if not credential:
raise Exception('login required')
else:
g.cred = credential
return func(*args, **kwargs)

return Wrapped


def enforce_policy(rule ):
"""对 API 执行策略。"""
def wrapper(func):
"""用于包装 API 的装饰器。"""
@functools.wraps(func)
def Wrapper(*args, **kwargs):
if enforcer.enforce(rule, {}, g.cred):
return func(*args, **kwargs)

return Wrapped

return wrapper


@app. route('/user', methods=['GET'])
@login_required
@enforce_policy('user:create')
def create_user():
# do create action
return 'user created'


@app.route('/article' , methods=['GET'])
@login_required
def delete_article():
article_name = request.args.get('name')
article =articles.get(article_name)

# 在这里做细粒度权限检查
enforcer.enforce('article :删除',文章,g.cred)
# 在此处执行删除操作
return 'arcicle %s deleted' % article['id']


if __name__ == '__main__':
app.run(port=8888, debug=True)
```

#### View-Level

We提供一个``enforce_policy`` 装饰器来对视图``create_user`` 执行策略。

我们前往 http://127.0.0.1:8888/user?me=kate 来模拟 ``kate`` 的创建用户并得到一个错误:

user:create on {} by {'roles': ['user' ], 'id': '1a535309687244e2aa434b25ef4bfb59'} 被策略禁止

然后我们前往 http://127.0.0.1:8888/user?me=lily 来模拟 ``lily`` 的创建用户并获得成功的响应:

user创建

####细粒度

在某些情况下,我们需要细粒度的权限检查。我们在视图“delete_article”内执行策略,因为在视图之外我们无法知道用户想要删除哪篇文章。

我们前往 http://127.0.0.1:8888/article?me=lucy&name=python 来模拟 lucy 删除文章并得到错误:

article:delete on {'user_id': '1a535309687244e2aa434b25ef4bfb59', ' id': 'e6e31ad693734b269099d9acac2cb800'} by {'roles': ['user'], 'id': '186977181e7f4a9e85104ca017e845f3'} 政策不允许

然后我们前往 http://127.0.0.1:8888/article?me=kate&name= python 模拟 kate 删除文章并获得成功响应,因为 kate 是文章的所有者:



最后我们访问 http://127.0.0.1:8888/article?me=lily&name=python 来模拟 ``lily`` 删除文章并获得成功响应,因为``lily`` 是管理员角色用户:

arcticle e6e31ad693734b269099d9acac2cb800 已删除


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

policy-1.0.0.zip (21.0 kB 查看哈希

已上传 source

内置分布

policy-1.0.0-py3-none-any.whl (11.5 kB 查看哈希

已上传 py3