金字塔授权的存储项目

发布于 2021-01-29 17:04:25

我正在尝试创建一个将“项目”所有权考虑在内的授权策略。例如,一些用户X“拥有”项目A,B,C。这些项目可通过诸如URL进行访问/item/{item}/some_options

如何获取有关{item}授权策略对象的信息(permits()调用)?将更多信息放入上下文是一个好主意(我仅在进行基于路由的路由)。我该怎么办?

关注者
0
被浏览
120
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您可以使用ACLAuthorizationPolicy为此目的而设计的自定义资源树,并结合使用URL调度和URL调度。

    例如,您具有Foo对象的权限和Bar对象的权限。这些ACL可以通过使用url遍历资源树来找到:

    /foos/{obj}
    /bars/{obj}
    

    然后,您的资源树将成为权限层次结构,您可以在树中的任何时候在__acl__资源对象上放置一个:

    root                       (Root)
    |- foos                    (FooContainer)
    |  `- {obj}                (Foo)
    `- bars                    (BarContainer)
       `- {obj}                (Bar)
    

    您可以在资源树中表示此层次结构:

    class Root(dict):
        # this is the root factory, you can set an __acl__ here for all resources
        __acl__ = [
            (Allow, 'admin', ALL_PERMISSIONS),
        ]
        def __init__(self, request):
            self.request = request
            self['foos'] = FooContainer(self, 'foos')
            self['bars'] = BarContainer(self, 'bars')
    
    class FooContainer(object):
        # set ACL here for *all* objects of type Foo
        __acl__ = [
        ]
    
        def __init__(self, parent, name):
            self.__parent__ = parent
            self.__name__ = name
    
        def __getitem__(self, key):
            # get a database connection
            s = DBSession()
            obj = s.query(Foo).filter_by(id=key).scalar()
            if obj is None:
                raise KeyError
            obj.__parent__ = self
            obj.__name__ = key
            return obj
    
    class Foo(object):
        # this __acl__ is computed dynamically based on the specific object
        @property
        def __acl__(self):
            acls = [(Allow, 'u:%d' % o.id, 'view') for o in self.owners]
            return acls
    
        owners = relation('FooOwner')
    
    class Bar(object):
        # allow any authenticated user to view Bar objects
        __acl__ = [
            (Allow, Authenticated, 'view')
        ]
    

    通过这样的设置,您可以将路由模式映射到资源树:

    config = Configurator()
    config.add_route('item_options', '/item/{item}/some_options',
                     # tell pyramid where in the resource tree to go for this url
                     traverse='/foos/{item}')
    

    您还需要将路线映射到特定视图:

    config.add_view(route_name='item_options', view='.views.options_view',
                    permission='view', renderer='item_options.mako')
    

    太好了,现在我们可以定义视图并使用加载的上下文对象,知道如果执行了该视图,则用户具有适当的权限!

    def options_view(request):
        foo = request.context
        return {
            'foo': foo,
        }
    

    使用此设置,您将使用默认值ACLAuthorizationPolicy,并通过URL
    Dispatch为对象提供行级权限。另请注意,由于对象__parent__在子级上设置了属性,因此该策略将沿袭父辈的权限,使沿袭起泡。只需DENY_ALL在ACL中放入ACE,或编写不使用上下文沿袭的自定义策略,就可以避免这种情况。

    更新 我已将这篇文章变成Github上的实际演示。希望它可以帮助某人。
    https://github.com/mmerickel/pyramid_auth_demo

    更新
    我已经在此处撰写了有关金字塔认证和授权系统的完整教程:http
    :
    //michael.merickel.org/projects/pyramid_auth_demo/



推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看