[Twisted-Python] What are the relationships between twisted.cred.portal.IRealm, Portal and avatar

Glyph Lefkowitz glyph at twistedmatrix.com
Thu Dec 17 04:45:45 MST 2015


> On Dec 13, 2015, at 7:50 AM, Wang Yan <snailcoder at 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20151217/d41a495a/attachment-0002.html>


More information about the Twisted-Python mailing list