[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