HTTP禁止上下文路由未触发

3 投票
3 回答
875 浏览
提问于 2025-04-17 04:21

我在使用Pyramid框架时遇到了一些安全性方面的问题。我的安全设置似乎是正常的:如果用户试图访问他们没有权限查看的资源,Pyramid会抛出一个HTTPForbidden异常。问题是,在这种情况下,它应该自动跳转到登录页面,但实际上并没有发生。我只看到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

我所有的视图都有一个默认权限设置为'view',我的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文件中移除默认权限,所有功能就都正常了。

如果有人能给我一些建议,告诉我哪里出了问题,我会非常感激。

3 个回答

0

你可能需要在你的视图配置中加上“permission=NO_PERMISSION_REQUIRED”。

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

你的 groupfinder() 函数应该在所有情况下都返回一个列表。如果用户不在任何组里,就返回 [],而不是 None

我不确定这是否是你的问题。不过我遇到过类似的情况,当我返回 None 而不是 [] 时,程序的表现就不对了。

1

这可能和你的问题没什么关系,但在Pyramid框架中,基于类的视图工作方式是一个两步的过程。第一步,Pyramid会用一个叫做request的对象来创建你的类的实例;第二步,Pyramid会调用__call__方法,或者调用在view_config中指定的attr方法。所以,在你的__init__里调用self.__call__()是不对的。

你使用基于类的视图的方式有点不太常规,但我在你提供的代码中没有看到实际的错误。

撰写回答