[Twisted-web] HTTP authentication and Nevow cred checker

Jean-Paul Calderone exarkun at divmod.com
Mon Jan 29 07:14:21 CST 2007


On Mon, 29 Jan 2007 13:50:06 +0100, KC Leong <mewanttowork at gmail.com> wrote:
>Hello,
>
>With Twisted and Nevow I'm building an XML-RPC server that does HTTP
>authentication. So a basic XML-RPC client can login using
>https://user:passwd@host. I can get the credentials with HTTP
>authentication, but how can I check the credentials. I'd tried calling
>guard.SessionWrapper.login(....), but I get the error: 
>"exceptions.TypeError:
>unbound method login() must be called with SessionWrapper instance as first
>argument (got NevowRequest instance instead)".

As its name suggests, SessionWrapper is a wrapper.  You're not intended to
call unbound methods from it with instances of an unrelated class. ;)

>
>So I'm guessing that request.getSession() is wrong and I must get the
>session of the guard (or something similar). Or I'm calling the wrong
>function to check the creds. In the guarded.py example from Nevow the
>credentials get checked thru a html form, but that is not what I want.
>
>Below is an example part of my code:
>
>class RootPage(rend.Page):
>    ## We are a directory-like resource because we are at the root
>    addSlash = True
>    ## Doesn't work
>    def tryLogin(self, ctx, request):
>        session =  request.getSession()
>        segments = inevow.ICurrentSegments(ctx)
>        httpAuthCredentials = (self.data_username,self.data_password)
>        return guard.SessionWrapper.login(request, session,
>httpAuthCredentials, segments).addCallback(self._loginSucceeded).addErrback(
>self.loginFailed)
>
>    def renderHTTP(self, ctx):
>        request = inevow.IRequest(ctx)
>        username, password = request.getUser(), request.getPassword()
>        ## No REAL authentication yet, must implement it.
>        if (username, password) == ('', ''):
>            request.setHeader('WWW-Authenticate', 'Basic
>realm='+cfg.app_name)
>            request.setResponseCode(http.UNAUTHORIZED)
>            return "Authentication required."
>        ## They provided a username and password, so let's let them in!
>horray
>        self.data_username, self.data_password = username, password
>
>        self.tryLogin(ctx, request)
>        return rend.Page.renderHTTP(self, ctx)
>

All of this is unnecessary.  Get rid of it and instead, wrap your page in
a SessionWrapper and use the SessionWrapper as your resource.  Take a look
at <http://divmod.org/trac/browser/trunk/Nevow/examples/guarded/guarded.py>,
particularly the createResource function at the end, which closely resembles
what you want to do instead of the above.

>    docFactory = loaders.stan(tags.html[
>    tags.body[
>        tags.h1["Welcome user!"],
>        tags.div["You said: ",
>            tags.span(data=tags.directive('username'), render=str),
>            " ",
>            tags.span(data=tags.directive('password'), render=str),
>            tags.a(href=guard.LOGOUT_AVATAR)["Logout"]
>            ]]])

This stuff will then end up on the wrapped resource, and only be accessible
after SessionWrapper decides authentication has occurred.

Jean-Paul



More information about the Twisted-web mailing list