策略库为 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 已删除
策略库为 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
查看哈希)
内置分布
policy-1.0.0-py3-none-any.whl
(11.5 kB
查看哈希)
关
policy-1.0.0.zip的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 66b747f621d74d60184f4155ad01510b81e150e15cd596a4de99d48e9fd2f182 |
|
MD5 | 41c218ba3db230cf1b5691de0bfdbda1 |
|
布莱克2-256 | 8cfcb9d9ea164165f704fe3ddf0f9d8f3b3f63fb96f7c9bfdcbeb7eb1c05b2a6 |