首页 > 解决方案 > 扭曲的基本 HTTP 身份验证不起作用

问题描述

我有以下代码:

import sys

from zope.interface import implementer

from twisted.python import log
from twisted.internet import reactor
from twisted.web import server, resource, guard
from twisted.cred.portal import IRealm, Portal
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse


class GuardedResource(resource.Resource):
    """
    A resource which is protected by guard and requires authentication in order
    to access.
    """
    def getChild(self, path, request):
        return self


    def render(self, request):
        return "Authorized!"



@implementer(IRealm)
class SimpleRealm(object):
    """
    A realm which gives out L{GuardedResource} instances for authenticated
    users.
    """

    def requestAvatar(self, avatarId, mind, *interfaces):
        if resource.IResource in interfaces:
            return resource.IResource, GuardedResource(), lambda: None
        raise NotImplementedError()

def main():
    log.startLogging(sys.stdout)
    checkers = [InMemoryUsernamePasswordDatabaseDontUse(joe='blow')]
    portal = Portal(SimpleRealm(), checkers)

    resource = guard.HTTPAuthSessionWrapper(portal, [guard.BasicCredentialFactory('auth')])

    reactor.listenTCP(8889, server.Site(resource = resource))
    reactor.run()

if __name__ == '__main__':
    main()

当我们启动服务器并访问 url 时: http://localhost:8889/弹出一个提示,要求我们输入用户名和密码。进入后user = joepassword = blow我们仍然无权访问该网站。上面的代码有什么问题以及如何解决?

标签: twistedtwisted.web

解决方案


所以我按照@Jean-Paul Calderone 的建议在 trac 上发布并在这里解决了问题

有 2 件事需要解决

  1. 渲染方法在python3中返回字节
    def render(self, request):
        return "Authorized!".encode('utf8')
  1. 里面的密码InMemoryUsernamePasswordDatabaseDontUse必须是字节
    checkers = [InMemoryUsernamePasswordDatabaseDontUse(joe=b'blow')]

因此,为了让您的代码在 py2 和 py3 中运行,请使用它

from __future__ import print_function
import sys
from zope.interface import implementer
from twisted.python import log
from twisted.internet import reactor
from twisted.web import server, resource, guard
from twisted.cred.portal import IRealm, Portal
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse


class GuardedResource(resource.Resource):
    """
    A resource which is protected by guard and requires authentication in order
    to access.
    """
    def getChild(self, path, request):
        return self


    def render(self, request):
        return "Authorized!".encode('utf8')


@implementer(IRealm)
class SimpleRealm(object):
    """
    A realm which gives out L{GuardedResource} instances for authenticated
    users.
    """

    def requestAvatar(self, avatarId, mind, *interfaces):
        if resource.IResource in interfaces:
            return resource.IResource, GuardedResource(), lambda: None
        raise NotImplementedError()

def main():
    log.startLogging(sys.stdout)
    checkers = [InMemoryUsernamePasswordDatabaseDontUse(joe=b'blow')]
    portal = Portal(SimpleRealm(), checkers)

    resource = guard.HTTPAuthSessionWrapper(portal, [guard.BasicCredentialFactory('auth')])

    reactor.listenTCP(8889, server.Site(resource = resource))
    reactor.run()

if __name__ == '__main__':
    main()

推荐阅读