twisted.cred.portal.IRealm、Portal和头像是什么关系

What are the relationships between twisted.cred.portal.IRealm, Portal and avatar

我正在尝试使用 Twisted 的 HTTP 基本身份验证来控制对某些受保护资源的访问。

根据一些文章,需要用到三个重要的概念:Realm,Portal,avatar。现在想知道Realm和avatar是不是一一对应的

我们来看一个例子

import sys

from zope.interface import implements

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!"



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

    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')]
    wrapper = guard.HTTPAuthSessionWrapper(
        Portal(SimpleRealm(), checkers),
        [guard.DigestCredentialFactory('md5', 'example.com')])
    reactor.listenTCP(8889, server.Site(
          resource = wrapper))
    reactor.run()

if __name__ == '__main__':
    main()

我当然知道SimpleRealm是用来return对应资源的,例如上例中的 GuardedResource。但是,当有很多资源需要保护时,我不知道该怎么办。比如我有GuardedResource1、GuardedResource2和GuardedResource3,它们在初始化的时候可能需要相同或不同数量的参数;如果是这样,是否需要分别实现SimpleRealm1、SimpleRealm2和SimpleRealm3?

有人在 Twisted 邮件列表上问过同样的问题,代码示例非常相似 - http://twistedmatrix.com/pipermail/twisted-python/2015-December/030042.html - so I'll refer you to my answer there: http://twistedmatrix.com/pipermail/twisted-python/2015-December/030068.html

Rather than thinking of a resource as always existing and just needing to have a lock on it or not, consider the more flexible model (the one that cred actually implements) where a single Avatar object (in this case: the top IResource returned from SimpleRealm) is the top level of "everything the user has access to". In other words, 'GuardedResource' should have a 'getChild' method which makes the determination if the user they represent (really, at least the avatarId should be supplied to GuardedResource.init) has access to other resources, and return them if so, and appropriate errors if not.

Even the resources available to a not-logged-in user (see twisted.cred.credentials.Anonymous) is just another avatar, the one served up to unauthenticated people.

So, if you have https://myapp.example.com/a/b/secure/c/d https://myapp.example.com/a/b/secure/c/d, https://myapp.example.com/a/b/secure https://myapp.example.com/a/b/secure would be the guarded resource, and then SecureResource.getChild("c", ...) would return "c", which would in turn return "d" if the logged-in user has access to it.

希望这个答案在列表中对您有用 :-)。