金字塔授权 - 自定义视图

时间:2017-02-14 18:51:08

标签: python authorization pyramid

目前我使用简单的SQLAlchemy + URL Dispatch身份验证设置(不使用金字塔的授权方法),也就是说,当用户无法执行某些操作时,我只会提出HTTPForbidden(这些检查发生在各个地方,包括验证变形等时。)。

对于一个新项目,我想尝试使用金字塔的授权方法,但我在定制视图方面遇到了困难。

当前理解

  1. 每个视图(我使用@view_config装饰器)都可以有一个权限字符串。通常'阅读'并且'写',但可以是任何字符串,真的。 Multiple permissions in view_config decorator?
  2. 每个用户都可以拥有多个主体(从SQLAlchemy + URL Dispatch tutorial收集)
  3. 主体和权限字符串之间的链接是authorization policy,这意味着多个主体可以具有相同的权限字符串。
  4. 对于the example博客文章等,这似乎相当简化,其中定义__acl__允许指定谁可以访问特定页面,以及每个人都可以阅读但只有这两个角色可以编辑'有道理。

    瓶颈

    第1点。每个视图必须有一个且只有一个权限字符串似乎是次优的。 link in point 1就是一个例子,其中一个' readwrite'必须使用权限字符串。

    特别是我想创建一个策略,允许用户A和B查看特定视图(项目列表),但用户A可以编辑该页面中的某些字段,而用户B可以编辑某些其他字段(可能重叠)。现在可以实现的方法: -

    1. 在我的表单验证(或request.POST检查)中,我可以check if a user has permissions
    2. 在我的表单生成中(我使用变形)我可以运行相同的检查以将某些字段标记为只读。
    3. 在我的模板中,我可以根据需要运行相同的检查来隐藏/显示字段。
    4. 每个提交都会点击不同的网址,其中包含指定特定权限字符串的精简视图,并重定向回POST的原始页面(仅当传递了视图授权时)。
    5. 前三个看起来相当笨重,因为它们正是我之前所做的(除了现在我需要使用has_permission而不是手动检查request.user.role或request.user.id )。

      第四个似乎更正确&#39;利用金字塔身份验证/授权,但需要一大堆新的URL,路由和视图才能实现此目的。基本上增加了很多复杂性,我可以通过使用金字塔的授权方法在security.py <body onload="window.location = 'http://example.com/'"> 中解决这个问题。

      摘要

      我是否因为授权如何让我的生活变得更轻松而错过了一些东西,因为与我的手动检查相比,上述所有内容似乎都增加了开销和代码复杂性(我想要摆脱它,因为这会使身份验证分布在我的代码中,在模板中,在视图中,甚至有时在模型中。)

1 个答案:

答案 0 :(得分:1)

以下是一个选项:您的视图受一般权限的保护,指定用户是否可以查看/提交表单,然后您拥有更精细的权限,您可以手动检查代码:

@view_config(..., permission='view-kittens')
def view_kitten(request):
    data = {}
    kitten = fetch_kitten_from_db(request.matchdict['id'])
    if request.has_permission('view-kitten-name'):
        data['name'] = kitten.name
    if request.has_permission('view-kitten-color'):
        data['color'] = kitten.color
    return data

@view_config(..., permission='edit-kittens')
def edit_kitten(request):
    kitten = fetch_kitten_from_db(request.matchdict['id'])
    if request.has_permission('edit-kitten-name'):
        kitten.name = request.POST['name']
    if request.has_permission('edit-kitten-color'):
        kitten.color = request.POST['color']
    kitten.save()
    ...

另一个选择是拥有更精细的视图函数集,每个函数都受单个权限保护:

@view_config(..., permission='edit-kitten-name')
def edit_kitten_name(request):
    ...

@view_config(..., permission='edit-kitten-color')
def edit_kitten_color(request):
    ...

这可能不会与Deform一起发挥,但对于某种AJAX前端会很好。