> On Dec 13, 2015, at 7:50 AM, Wang Yan <snailco...@163.com> wrote: > > I'm trying to use Twisted's HTTP basic authentication to control access to > some protected resources. > > According to some articles, it is necessary to use three important concepts: > Realm, Portal and avatar. Now I'm wondering if the Realm and avatar is one to > one correspondence.
The idea is that a Realm represents an application, and an Avatar represents a single user's data within that application. This example is a bit oversimplified, since it doesn't provide any inputs to the user's data; most of the time, you'd want to retrieve a session or something based on the avatarID. > Let's look at an > example(http://www.red-bean.com/doc/python-twisted-web/examples/webguard.py): > > 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() > > Of course I know the SimpleRealm is used to return the corresponding > resource, e.g. GuardedResource in above example. However, I don't know what > to do when there lots of resources to be guarded. For example, I have > GuardedResource1, GuardedResource2 and GuardedResource3, maybe they need the > same or different number of parameters when they are initialized; If so, is > it necessary to implement SimpleRealm1, SimpleRealm2 and SimpleRealm3, > respectively? 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. Does this make sense? Thanks for using Twisted, -glyph
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python