偶尔禁用 Pyramid 中间件

Posted

技术标签:

【中文标题】偶尔禁用 Pyramid 中间件【英文标题】:Occasionally disabling Pyramid middleware 【发布时间】:2013-06-10 18:04:57 【问题描述】:

注意:如果有帮助,我使用的是 Pyramid 1.3.2。我知道它有点过时了,我不希望立即更新,但如果最新版本对此用例提供更好的支持,我可能会强制更新。

我正在开发的基于 Pyramid 的应用程序具有严格的授权策略:所有调用必须经过身份验证。由于 1) 在每个请求处理程序上手动添加它很乏味; 2)我们不希望任何人“忘记”添加身份验证,我们使用一个简单的 Pyramid 中间件(补间)在服务器范围内强制执行此操作,以验证所有传入请求。

最近,这个限制稍微放宽了:偶尔,一些资源应该支持(安全和幂等)GET,无需身份验证。

这似乎与大多数 Web 框架中身份验证背后的通常设计理念(可选身份验证)直接相反,所以我无法让它按预期工作。

问题:实现授权中间件的正确方法是什么?该中间件默认验证和验证授权,但可以在逐个视图的基础上禁用?


到目前为止,我已经尝试像这样添加一个简单的装饰器:

def allows_anonymous_access(f):
  f.allows_anonymous_access = True; return f

@allows_anonymous_access
def my_pyramid_view(request):
  # ...

在我的中间件中,我想这样使用它:

def authorization_middleware(handler, registry):
  def verify_authorization(request):
    # Identify the user making the request.  Make sure we get the
    # user's identify if provided, even when the request handler
    # allows anonymous access.
    try:
      request.principal = extract_user(request)
    except InvalidCredentials, error:
      if getattr(handler, 'allows_anonymous_access', False):
        request.principal = AnonymousUser()
      else:
        raise HTTPUnauthorized(...)
    # Invoke the handler.
    return handler(request)
  # Middleware that will pre/post-process the request.
  return authorization_middleware

但是,当中间件执行时,handler 不是我的看法。它恰好是一个绑定方法 (pyramid.router.Router.handle_request),它不让我访问可调用的视图,这意味着我无法访问中间件设置的标志。

【问题讨论】:

Pyramid 有自己的身份验证系统。我强烈建议尝试使用它而不是自己编写。您所要求的在框架内部非常简单,可能比您在这个问题中粘贴的代码少。 Piotr 提供的答案是正确的,但是如果不配置 ACL 和 authn/authz 策略,您将很难使用它。这里还有其他几个关于 SO 讨论如何做到这一点的问题。 【参考方案1】:

你可能想要pyramid.config.set_default_permission(permission)。来自docs:

添加默认权限使得无需保护每个视图 具有显式权限的配置,除非您的应用程序 政策要求特定视图有一些例外。

如果默认权限有效,则查看配置 创建一个真正匿名可访问的视图(甚至 异常视图 视图) 必须使用可导入权限的值作为 pyramid.security.NO_PERMISSION_REQUIRED。当此字符串用作 permission 用于查看配置,默认权限为 忽略,并注册视图,使其可供所有人使用 调用者,无论其凭据如何。

raydeo_ 在#pyramid freenode IRC 频道上提供的答案。

【讨论】:

以上是关于偶尔禁用 Pyramid 中间件的主要内容,如果未能解决你的问题,请参考以下文章

Mycat中间件:后端服务器上drop db然后重新创建相同名称的db,查询时会偶尔报错:1046-no database selected

如何在特定页面禁用中间件,nuxt 中间件

如何在 Symfony Messenger 的中间件上禁用日志“信息”?

在 Laravel 5 中,如何禁用特定路由的 VerifycsrfToken 中间件?

在 laravel 5.2 中禁用特定路由的 Web 中间件

如何在不使用 redux 中间件的情况下禁用/隐藏自适应卡片/操作按钮?