Mar*_*ann 2 python acl pyramid
我正在尝试为我正在构建的应用程序工具箱创建一个安全系统。我以前有一个 acl,但问题是我无法在基于应用程序的级别上进行控制。
基本上,我认为我需要的是将应用程序 GUID 传递给函数groupfinder(),但我不确定应该如何处理这个问题。有人有什么想法吗?
groupfinder金字塔中的 和旨在context factory单独且隔离地运行。前者用于定义“当前用户”,后者用于定义“当前资源”。这两项最终结合起来permission通过授权策略的permits功能来判断“当前用户”是否有“权限”操作这个“资源”。
负责groupfinder识别用户。这意味着将它们转换为一组稍后可以使用的主体。
确定context factory当前资源(上下文)...因此每个 url 通常应该不同(记住 URL 中的 R 是资源),因此 url 通常定义资源。
附加到 url 的视图定义了permission所需的内容(对于视图执行的操作)。
这里的第二步是人们来到金字塔时最难理解的。如何为每个 URL 定义此资源?url 调度教程 [1] 中对此进行了介绍,但我将在这里快速解释。
正如我上面所说,每个路由通常代表一个资源,因此我们可以通过为该路由定义一个对象将其放入代码中。这是通过factory参数来完成的config.add_route(..., factory=...),它可以使用路由做很多事情来确定当前资源是什么。
def page_factory(request):
# I'm attached to a page so I can grab the matchdict
pageid = request.matchdict['pageid']
page = request.db.query(Page).get(pageid)
if page is None:
raise HTTPNotFound
return page
config.add_route('page', '/pages/{pageid}', factory=page_factory)
Run Code Online (Sandbox Code Playgroud)
此代码片段定义了一个带有页面工厂的路由,并且附加到该路由的每个视图都将将该页面作为上下文 ( request.context)。
这里的对象Page有一个 ACL,定义允许哪些用户/组(主体)对其执行哪些操作(权限)。
class Page(Base):
__tablename__ = 'page'
# a bunch of columns
def __acl__(self):
return [
(Allow, f'app:{self.app.id} user:{self.owner_id}', 'edit'),
(Allow, f'app:{self.app.id}', 'read'),
]
Run Code Online (Sandbox Code Playgroud)
假设此页面附加到 app1,我们可以轻松定义一个 groupfinder,表示 app1 中的任何人都可以读取它:
def groupfinder(userid, request):
user = request.db.query(User).get(userid)
if user is not None:
principals = []
for app in user.apps:
principals += [
f'app:{app.id}',
f'app:{app.id} user:{user.id}',
]
for group in app.groups:
principals += [f'app:{app.id} group:{group.id}']
return principals
Run Code Online (Sandbox Code Playgroud)
groupfinder 不了解页面,但它以足够的粒度描述用户,以便页面可以将用户与其允许的操作相匹配。
[1] https://docs.pylonsproject.org/projects/pyramid/en/1.9-branch/tutorials/wiki2/authorization.html
| 归档时间: |
|
| 查看次数: |
381 次 |
| 最近记录: |