【问题标题】:pyramid - how to configure multiple forbidden view depend on resource factory?金字塔 - 如何配置多个禁止视图取决于资源工厂?
【发布时间】:2013-07-16 10:35:14
【问题描述】:

我有一个金字塔项目,有 2 个部分:

  • /_hq/ 需要通过登录页面进行身份验证
  • /_rest/ 需要 RESTful 身份验证(通过 HTTP 基本/摘要式身份验证)

所以,我添加了 2 个主要资源工厂的路由:HQFactoryRESTFactory。我已经构建了一个身份验证策略切换器来切换每个资源的 AuthenticationPolicy。它奏效了。

我也使用 ACLAuthorizationPolicy。

对于每个请求,我想返回一个登录页面401 HTTP状态取决于正在访问的资源工厂。

我的问题是我只能为一个视图执行 @forbidden_​​view_config。如何为每个资源工厂指定出价视图或针对我的问题的其他解决方案?

谢谢

已解决 - 解决方案

最简单的方法是 Michael Merickel 的回答(您可以在下面看到)。这里还有另一种方式:

已弃用

我通过使用 view_config 中的 custom_predicates arg 解决了我的问题。就是这样。

我创建了一个函数作为自定义谓词:

def resource_factory_predicate(factory):
    def check_factory(context, request):
        return isinstance(request.context, factory)
return check_factory

然后,这是我的意见.py

# views.py
@forbidden_view_config(
custom_predicates=(resource_factory_predicate(RootFactory),))
def login_required(request):
    userid = authenticated_userid(request)

    if userid is not None:
        return HTTPForbidden("You're not authorized for this action")

    # redirect to login page


@forbidden_view_config(renderer='json',
    custom_predicates=(resource_factory_predicate(RESTfulFactory),))
def http_403_unauthenticated(request):
    request.response.status = 403
    return {
        'status': 0,
        'message': 'Forbidden',
    }

【问题讨论】:

  • 为什么你只能为一个视图做@forbidden_view_config? Pyramid 没有限制它。使用谓词注册两个这样的视图。
  • 是的,我考虑过将上下文传递给@forbiden_view_config,但它有限制作为我对您的回答的评论。

标签: authentication pyramid


【解决方案1】:

虽然您不能根据上下文调度异常视图(异常用作上下文),但可以作弊并使用containment 选项,该选项要求指定类型在实际的lineage 中语境。这意味着如果它下面的任何上下文引发异常,它也会匹配,从而影响遍历层次结构的整个子树。

@forbidden_view_config(containment=MyRootA)
def root_a_forbidden(exc, request):
    # note that the actual context is available on request.context
    pass

@forbidden_view_config(containment=MyRootB)
def root_b_forbidden(exc, request):
    pass

【讨论】:

  • 哇,非常感谢。此解决方案更简单、更易于实施。
【解决方案2】:

禁止的观点与其他观点一样,真的;见@forbidden_view_config() decorator documentation:

pyramid.view.view_config 的类似物,它注册了一个禁止视图

forbidden_view_config 构造函数接受大部分与pyramid.view.view_config 构造函数相同的参数。它可以在相同的地方使用,并且行为方式大致相同,只是它总是注册一个禁止的异常视图而不是“正常”视图。

这意味着它接受与pyramid.view.view_config() 相同的谓词;装饰器基本上调用add_forbidden_view(),这意味着它的参数可以在装饰器中使用;该方法的文档明确排除了context,但路由名称​​是一个选项:

@forbidden_view_config(route_name='hq'):
def forbidden_for_hq(request):
    # ...

@forbidden_view_config(route_name='rest'):
def forbidden_for_rest(request):
    # ...

如果要映射的路线太多,请考虑使用custom predicate。您已经拥有自定义身份验证策略切换器;您需要做的就是添加一个自定义谓词,该谓词将检测正在使用的策略。

【讨论】:

  • 我尝试了您的解决方案,但无法将上下文参数传递给 disabled_view_config。它将引发 ConfigurationError 异常'context may not be used as a argument to add_forbidden_​​view'
  • Blergh,那是文档失败。您首先使用哪些谓词来选择上下文?也许您可以将路线用作谓词?
  • 我有很多用于 HQ 和 REST 的路由,如果我使用路由而不是上下文,我将不得不指定很多路由,并且每当我添加新路由时都更新禁止的装饰器,这太难了。
  • 谢谢你,路线名称让我很难受。我找到了一个参数名称“custom_predicate”。现在我正在谷歌上搜索它。根据您的经验,我可以解决我的问题吗?
  • 当然;您已经拥有自定义身份验证策略切换器;您需要做的就是添加一个自定义谓词来检测正在使用的策略。
猜你喜欢
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2014-08-03
  • 2020-11-01
相关资源
最近更新 更多