2

Note: If it's any help, I'm using Pyramid 1.3.2. I know it's a little out of date, I would prefer not to update right away, but I might be able to force an update if the latest version provides better support for this use case.

The Pyramid-based application I'm working on has a strict authorization policy: all calls must be authenticated. Since 1) it's tedious to add this manually on every request handelr; and 2) we don't want anybody to "forget" adding authentication, we enforce this server-wide using a simple Pyramid middleware (tween) that verifies all incoming requests.

Recently, this restriction has been slightly relaxed: occasionally, some resources should support (safe & idempotent) GET without authentication.

It seems this is directly opposed to the usual design ideas behind authentication in most web frameworks (optional authentication), so I can't get it to work quite as expected.

QUESTION: What is the correct approach to implementing an authorization middleware that authenticates & verifies authorization by default, but can be disabled on a view-by-view basis?


So far, I've tried adding a simple decorator like so:

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

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

In my middleware, I would like to use it like this:

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

However, when the middleware executes, handler is not my view. It happens to be a bound method (pyramid.router.Router.handle_request) which does not provide me access to the view callable, meaning I cannot access the flag set by the middleware.

4

1 回答 1

0

你可能想要pyramid.config.set_default_permission(permission). 来自文档

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

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

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

于 2013-06-10T20:59:43.720 回答