在Pyramid中实现认证/授权
我按照文档中的说明 组级安全
写了这些代码:
def groupfinder(userid, request):
print '#'*80
print userid
role = DBSession.query(Role)....
if role.name == "Admin":
return ['g:admin']
class RootFactory(object):
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, Authenticated, 'edit'),
(Allow, 'g:admin', 'admin')
]
def __init__(self, request):
pass
authn_policy = AuthTktAuthenticationPolicy(
settings['auth.secret'],
callback=groupfinder,
)
它是可以工作的,但每次加载页面时都会重复查询数据库
难道应该在用户第一次登录时就返回权限吗?
还是说我做错了什么...
我该如何在像mako这样的模板中知道权限“g:admin”呢?
1 个回答
6
你的 groupfinder
现在有一个小问题。它应该总是返回一个列表,只要用户是有效的。只有在没有用户的情况下,它才应该返回 None
。现在你只在用户是管理员时返回列表,所以普通用户永远不会被识别。
def groupfinder(userid, request):
print '#'*80
print userid
role = DBSession.query(Role)....
if role is not None:
principals = []
if role.name == "Admin":
principals.append('g:admin')
return principals
注意,我们总是返回一个列表,除非 role
是 None
。
接下来,你问到了性能问题。Pyramid 不会尝试缓存任何东西。不过,你可以自己轻松处理这个问题。通常的做法是在你的 request
对象上添加一个缓存的(具体化的)属性,里面存放 role
或 user
。这样每次调用 groupfinder
时,你就可以使用缓存的 role
,而不是再次查询它。这个模式可以在 这里 查看。
我怎么知道在像 mako 这样的模板中权限 "g:admin" 的情况?
其实 'g:admin' 在 Pyramid 的认证术语中是一个 主体。'admin'(你访问控制条目的第三个元素)是 权限。主体被视为实现细节,只是帮助我们将事物映射到权限上。最终,我们在处理访问/授权时,真正关心的只是权限。
要在你的模板中查看用户是否拥有该权限,你可以使用 pyramid.security.has_permission('admin', request.context, request)
。你可以用任何具有 __acl__
的对象替换 request.context
,但在这个场景中,request.context
将是你的 RootFactory
(这正是你想要的)。