HTTPForbidden上下文路由未触发

时间:2011-10-14 21:39:01

标签: python authentication pyramid

我在使Pyramid中的安全性正常工作时遇到了一些麻烦。我的安全性似乎正在起作用:如果用户试图访问他们无权查看的资源,Pyramid会抛出HTTPForbidden异常。问题是在这种情况下,它应该回退到登录视图,这不会发生。我只是使用stacktrace获取默认的Pyramid异常屏幕。

我的登录视图:

from pyramid.httpexceptions import HTTPForbidden

@view_config(context = HTTPForbidden, renderer="login.mak")
@view_config(route_name = 'login', renderer='login.mak')
class Login(ViewBase):
    def __init__(self, request):
        super(Login, self).__init__(request)
        self.data['title'] = "Login"

        if request.method == 'POST':
            name = request.params['username']
            passwd = request.params['password']
            validuser = User.check(name, passwd)
            if validuser is None:
                self.data['requested_path'] = request.params['requestpath']
                self.__call__()
            else:
                headers = remember(request, str(validuser.id))
                raise HTTPFound(
                    location = request.params['requestpath'],
                    headers = headers
                    )
        else:
            self.data['requested_path'] = request.url

    def __call__(self):
        return self.data

所有视图都将默认权限设置为“查看”,我的acl类如下所示:

from pyramid.security import Allow
from pyramid.security import Everyone
from pyramid.security import Authenticated
from pyramid.security import ALL_PERMISSIONS

# Handles ACL auth for the entire application

class RootFactory(object):

    __acl__ = [
        (Allow, Everyone, 'view'),
        (Allow, 'Editor', 'edit'),
        (Allow, 'Admin', ALL_PERMISSIONS)
    ]

    def __init__(self, request):
        pass

def groupfinder(userid, request):

    from ctic.models import User

    user = User.get(userid)
    member_groups = []
    if user != None:
        member_groups.append(user.group.groupname)
        return member_groups
    else:
        return None

正如我所说,ACL方面似乎有效。

有趣的是,如果我从init.py中删除default_permission,一切正常。

任何有关我出错的地方都会受到赞赏。

3 个答案:

答案 0 :(得分:1)

这可能与您的问题无关,但基于类的视图在Pyramid中的工作方式是它分为两个步骤。 1)金字塔使用request对象实例化您的类2)金字塔调用__call__方法或attrview_config指定的方法。因此,self.__call__()中对__init__的调用不正确。

您使用基于类的视图的方式有点不同寻常,但我没有看到您在此处粘贴的任何实际错误。

答案 1 :(得分:0)

您的groupfinder()应该在所有情况下都返回一个列表。如果用户不在任何群组中,请返回[]而不是None

我不确定这是不是你的问题。但是当我返回None而不是[]时,我遇到了类似的行为。

答案 2 :(得分:0)

您可能希望在view_config中添加“permission = NO_PERMISSION_REQUIRED”

from pyramid.security import NO_PERMISSION_REQUIRED
@view_config(context = HTTPForbidden, renderer="login.mak", permission=NO_PERMISSION_REQUIRED)