Occasionally disabling Pyramid middleware

落花浮王杯 提交于 2019-12-11 08:32:31

问题


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.


回答1:


You probably want pyramid.config.set_default_permission(permission). From docs:

Adding a default permission makes it unnecessary to protect each view configuration with an explicit permission, unless your application policy requires some exception for a particular view.

If a default permission is in effect, view configurations meant to create a truly anonymously accessible view (even exception view views) must use the value of the permission importable as pyramid.security.NO_PERMISSION_REQUIRED. When this string is used as the permission for a view configuration, the default permission is ignored, and the view is registered, making it available to all callers regardless of their credentials.

Answer provided by raydeo_ on #pyramid freenode IRC channel.



来源:https://stackoverflow.com/questions/17030095/occasionally-disabling-pyramid-middleware

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!