> 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

Reply via email to