对于存储物品的金字塔授权 [英] Pyramid authorization for stored items
问题描述
我试图创建一个以项目所有权在内的授权策略。例如,某些用户X拥有的项目A,B,C。这些是通过访问的URL,比如 /项目/ {}项/ some_options
。
I'm trying to create an authorization policy that takes "item" ownership into account. For example some user X "owns" items A, B, C. Those are accessed via URLs like /item/{item}/some_options
.
我怎样才能得到关于 {项目}
来授权策略对象(许可证()调用)的信息?是把附加信息的来龙去脉是一个好主意(我做的只是基于路由的路由)。我会怎么做呢?
How can I get the information about {item}
to the authorization policy object (permits() call)? Is putting additional information into context a good idea (I'm doing routes-based routing only). How would I do that?
推荐答案
您可以用这样做的 ACLAuthorizationPolicy
使用专为这种定制的资源树URL调度相结合目的。
You can do this using the ACLAuthorizationPolicy
combined with URL Dispatch by using a custom resource tree designed for this purpose.
例如,您有酒吧
对象为富
对象的权限,和权限。这些ACL可以通过使用网址遍历资源树中找到:
For example, you have permissions for Foo
objects, and permissions for Bar
objects. These ACLs can be found by traversing the resource tree using the urls:
/foos/{obj}
/bars/{obj}
您资源树就变成了权限,凡在树中的任何一点,你可以将 __ __ ACL
资源对象的层次结构:
Your resource tree then becomes a hierarchy of permissions, where at any point in the tree you can place an __acl__
on the resource object:
root (Root)
|- foos (FooContainer)
| `- {obj} (Foo)
`- bars (BarContainer)
`- {obj} (Bar)
您可以重新present这种层次结构中的资源树:
You can represent this hierarchy in a resource tree:
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')
]
通过这样的设置,您就可以路由模式映射到你的资源树:
With a setup like this, you can then map route patterns to your resource tree:
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}')
您还需要您的路线映射到特定的观点:
You will also need to map your route to a specific view:
config.add_view(route_name='item_options', view='.views.options_view',
permission='view', renderer='item_options.mako')
太好了,现在我们可以定义我们的观点,并使用加载的上下文对象,因为他们知道如果执行视图中,用户具有适当的权限!
Great, now we can define our view and use the loaded context object, knowing that if the view is executed, the user has the appropriate permissions!
def options_view(request):
foo = request.context
return {
'foo': foo,
}
使用此设置,您使用的是默认的 ACLAuthorizationPolicy
,而你与URL派遣你的对象提供行级权限。还要注意,因为对象设置 __ __父
属性的儿童,该政策将泡涨的血统,继承了父母的许可。这可以通过简单地把一个 DENY_ALL
ACE在ACL来避免或编写不使用上下文的血统的自定义策略。
Using this setup, you are using the default ACLAuthorizationPolicy
, and you are providing row-level permissions for your objects with URL Dispatch. Note also, that because the objects set the __parent__
property on the children, the policy will bubble up the lineage, inheriting permissions from the parents. This can be avoided by simply putting a DENY_ALL
ACE in your ACL, or by writing a custom policy that does not use the context's lineage.
*更新*
我把这个帖子到Github上实际演示。希望这可以帮助别人。
<一href=\"https://github.com/mmerickel/pyramid_auth_demo\">https://github.com/mmerickel/pyramid_auth_demo
*更新*
我已经写在这里金字塔的认证和授权系统中拥有完整教程:<一href=\"http://michael.merickel.org/projects/pyramid_auth_demo/\">http://michael.merickel.org/projects/pyramid_auth_demo/
这篇关于对于存储物品的金字塔授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!