首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查当前用户是否拥有金字塔服务的权限?

检查当前用户是否拥有金字塔服务的权限?
EN

Stack Overflow用户
提问于 2015-06-15 20:57:45
回答 1查看 1.1K关注 0票数 2

我在用科尼斯和金字塔和ACL八月。这是一个复制的老问题,我是重新问,因为金字塔已经改变。

当前文档pyramid.security.has_permission已经取代了request.has_permissionrequest.has_permission有一个可选的context arg。我试图在循环中使用has_permission来查看当前用户(request)可以访问哪些服务。

最终的目标是动态地扫描所有的Cornice服务(即使用Cornice的@resource装饰器查看文件),以查看哪些服务是为当前用户的给定权限(即'view')授权的。除了has_permission之外,我还愿意使用另一种方法来实现这一点。

这种知识的用例是提供一个Swagger文档,该文档只记录当前用户可用的API端点。

我希望代码看起来像这样:

代码语言:javascript
复制
from cornice import service
# Get our list of services
services = service.get_services()
# Assume we have an authenticated user logged in, thus attaching auth info to request
for svc in services:
    context = magic_context_function(svc)
    if request.has_permission('view', context) == False:
        # Code will go here to hide endpoint documentation for this endpoint
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-16 15:22:45

答案似乎应该是使用允许的(上下文、请求、名称=‘’),但我无法让它使用任意的视图名称,因为name arg与cornice.service.name值不匹配。

然而,这里有一个来自关于吉特卜的金字塔问题的半解。您需要几个导入才能使链接解决方案工作(更好)。这是完整的代码

代码语言:javascript
复制
from pyramid.security import _get_registry, Allowed
from pyramid.interfaces import IRouteRequest, IRequest, IViewClassifier, ISecuredView, IView
from zope.interface import providedBy
def route_view_execution_permitted(context, request, route_name, name=''):
    reg = _get_registry(request)
    context_iface = providedBy(context)
    request_iface = reg.queryUtility(
        IRouteRequest,
        name=route_name,
        default=IRequest)
    provides = (IViewClassifier, request_iface, context_iface)

    view = reg.adapters.lookup(provides, ISecuredView, name=name)
    if view is None:
        view = reg.adapters.lookup(provides, IView, name=name)
        if view is None:
            raise TypeError('No registered view satisfies the constraints. '
                            'It would not make sense to claim that this view '
                            '"is" or "is not" permitted.')
        return Allowed(
            'Allowed: view name %r in context %r for route %r (no permission defined)' %
            (name, context, route_name))
    return view.__permitted__(context, request)

可以使用上面的函数来确定当前用户(从request对象确定)是否能够访问服务(按名称),如下所示:

代码语言:javascript
复制
from cornice import service
services = service.get_services()
for svc in services:
  view_permitted = route_view_execution_permitted(request.context, request, svc.name)
  if view_permitted == True:
      # Do something interesting...

我发现上面的解决方案有两个缺陷:

  1. 这很慢,因为svc循环的每一次迭代都会以某种原因打开到API的新连接。
  2. 它返回一个错误的结果(即一个人对他没有的服务有权限,反之亦然)

也许有人能找到改进上面的答案的方法。同时,这里有一个解决方案,使用附加到每个服务的ACL,然后确定当前的request.effective_principals是否匹配。

代码语言:javascript
复制
# Now see if current user meets ACL requirements for any permission
is_permitted = None  # set our default.
for ace in acl:
    for principal in request.effective_principals:
        if ace[1] == principal:
            is_permitted = True if ace[0] == Allow else False
            break
    if is_permitted is not None:
        break

if is_permitted is True:
    # Do something interesting...

这里的缺点是:

  1. 由于与以前的解决方案相同的原因,它很慢
  2. 作为实现,它只查看@resource-decorated服务类,而不查看可能具有自己的权限或acls的@view-decorated方法。

这种情况可以通过以下方式加以补救:

代码语言:javascript
复制
for method, view, args in service.definitions:
    if 'permission' in args:
        # Now start looking at permission to see if they match what's given by the parent ACL in the resource class
        # Also, the special "__no_permission_required__" value means we should not have a Security Requirement Object
        if args['permission'] == NO_PERMISSION_REQUIRED :
            # Interesting....
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30854871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档