金字塔安全性:如何预先检测对视图的授权

时间:2018-07-23 08:13:03

标签: python authentication authorization pyramid

我有一个使用金字塔安全性的金字塔应用程序:https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html

它可以正常工作,即它完全按照我的意思保护我的应用程序,但是为了知道视图是否已授权“ I”(用户),唯一的方法是似乎进入视图本身并获得未经授权的页面。

是否可以提前知道 用户是否有权访问视图?这对于隐藏用户无权访问的链接很有用。

例如,在视图中,我想要一个类似的方法:

some_authorization_object.authorized_to_view('view_name')

或某些嘲笑。

提前谢谢

3 个答案:

答案 0 :(得分:1)

您需要声明具有ACL权限的工厂

class AdministrationFactory:
    def __init__(self, request):
        self.request = request
        self.__acl__ = [
            (Allow, 'role:admin', ALL_PERMISSIONS),
            (Allow, 'role:administration', ('create', 'read', 'update'))
        ]


def administration_factory(request):
    return AdministrationFactory(request)

并在您的路线中传递工厂对象

config.add_route('administration_team_index', '/administration/team', factory=administration_factory, request_method='GET')

答案 1 :(得分:1)

看看request.has_permission(在金字塔的旧版本中曾经是pyramid.security.has_permission)。它的工作方式与您的想象中的示例类似,只是您不需要向视图名称传递上下文和正在检查的权限名称:

if request.has_permission(context, 'access-site-settings'):
    show_site_settings_link = True

答案 2 :(得分:1)

多亏了回答者的帖子,我才能够设计出最终的解决方案。

最终解决方案的关键是request.registry.introspector.categorized()方法,该方法给出了一个(相当复杂但仍可读的)视图结构,并带有“权限”。这样,可以使用has_permission()方法找到查看视图所需的权限,最终可以确定用户是否有权访问该视图。

步骤如下:

  • 确认存在数据的分类结构,即: request.registry.introspector.categorized()

  • 获取与视图相关的权限的数据源,并使用我们感兴趣的视图(view_name)进行过滤:

    # Get a list of views:
    views_list = [
        v for v in request.registry.introspector.categorized() if v[0] == 'views'
    ][0][1]
    # From the list, select the one with the name we are looking for:
    related_permissions_source = [
        v["related"] for v in views_list if
        view_name in v["introspectable"].discriminator
    ]
    
  • 提取查看视图所需的权限名称列表:

    view_related_permissions = [ rel for rel in related_permissions_source[0] if rel.category_name == "permissions" ] permission_names = [ rper.discriminator for rper in view_related_permissions ]

  • 最后,对于view_related_permissions的每个元素,检查当前用户是否已获得授权:

    request.has_permission(permission)

用户第一次有权声明其对该视图具有权限。