List Info

Thread: Problem with digest authentication in RESTful app




Problem with digest authentication in RESTful app
country flaguser name
United States
2007-10-19 10:48:01
Hello,

I'm writing a web application/service using the RESTful
design
pattern. The app is a sheep breed society database. I'm
having a
problem with digest authentication using the method Robert
Brewer
suggested recently for contioional authorisation.

What I'm trying to acheive is as follows: anyone can go to
the domain
root and will get a web page offering them the choice of
either
logging in, or going to one of the resources (sheep data)
which
requires no authentication for GET verbs but does require
authentication for PUT, POST and DELETE. Every resource
apart from
this resource and the home page require authentication.

The directory structure is:
root
     /login
     /sheep
               /data
               /more resources....
     /members
              /member resources...

and so on. The root resource only supports GET and requires
no
authentication. /login is the resource users are linked to
when they
click the login link - they then get the browser
authentication dialog
and on completing that get a page with links to all the
other
resources. The /sheep/data resource should require no
authentication
for GET, but should require authentication for PUT, POST and
DELETE.
Using the web pages a user is either authenticated before
they get to
the /sheep/data resource, in which case they can make
requests with
all the verbs with no problem, or they get unauthenticated
access to
GET. Both these cases work fine. However when I tested the
case of an
unauthenticated POST to /sheep/data I first get the password
dialog,
and on entering the proper credentials, instead of running
the POST
method I get a 405 method not supported.

I put a few print statements into the cherrypy files, and
after
working back I found that the method passed to Request.run
in
_cprequest has the body of the POST request prepended to the
POST
methodname, so Resource.run sees something like
'SearchArg=&Search=SearchPOST', which of course leads
direct to a
405.  The first POST that triggers the 401 is fine.

The really wierd thing is that sometimes, for no reason I've
been able
to identify the POST request wil run OK the first time I try
it after
restarting muy app and the browser. Also the stuff prepended
to POST
differs according to the browser - I use Firefox mostly, but
with IE7
less of the body gets prepended, and with Opera nothing gets
prepended
by eventually cherrypy crashes with a socket timeout.  I've
looked at
the headers sent by firefox (with LiveHTTPheaders) and they
look OK.
I've tried thos both on a Windows XP machine and a Ubuntu
machine with
exactly the same result.

I'm a bit stuck, since my knowledge of python and the http
libraries
is not enough to enable me to work out where in the server
(or whether
in the server) the HTTP method is getting corrupted. I can't
find the
call to resource.run - probably because it's an indirect
call and I
can't work out where it might be called from.

If it were C I'd be looking for a buffer overflow and I'd
know how to
find it - but that's not supposed to happen in python - is
it?.

The relevant bit of my __init__.py, where the config is set
up is (I
know it's not very tidy, but I'm at the 'suck it and see'
stage with
cherrypy so bits have ben hacked in and out):

def conditional_digest_auth(verbs=['POST', 'PUT',
'DELETE']):
    """Turn on Digest auth based on various
criteria."""
    if cherrypy.request.method in verbs:
        cherrypy.tools.digest_auth._setup()


def get_users():
    return {'test' : 'test#'}


def StartApp(appconf, cp_conf, startfile):
    global dbConn


    _copyconf(appconf, startfile)

    # Get a connection to the database - shared between
cherrypy
threads
    dbConn =
psycopg2.connect(host='localhost',user='postgres',
password='exp<35get', database='sss_test')

    # Now load our modules
    import approot
    import sheep
    import flock
    import test

    # Configure CherryPy


    current_dir =
os.path.dirname(os.path.abspath(__file__))

    cherrypy.config.update(cp_conf)

    cherrypy.tools.conditional_digest_auth =
cherrypy.Tool('on_start_resource', conditional_digest_auth)

    # Create and mount the tree
    db = approot.Root()
    db.login = approot.Login()
    db.sheep = sheep.Sheep()
    db.sheep.data = sheep.Data()
    db.flock = flock.Flock()
    db.sheep.test = test.Test()

    conf = {'/': {'request.dispatch':
cherrypy.dispatch.MethodDispatcher(),
                   'tools.staticdir.root':current_dir}

             ,'/files': {'tools.staticdir.on':True,
                         'tools.staticdir.dir':'static'}

             ,'/login' : {'tools.digest_auth.on':True,
                         'tools.digest_auth.realm':'SSS
Database',
                         'tools.digest_auth.users':
get_users}

             ,'/sheep' : {'tools.digest_auth.on':True,
                         'tools.digest_auth.realm':'SSS
Database',
                         'tools.digest_auth.users':
get_users}

              ,'/sheep/data' : {'tools.digest_auth.on' :
False,
                               
'tools.conditional_digest_auth.on':
True,
                               
'tools.conditional_digest_auth.verbs':
['POST'],
                                'tools.digest_auth.realm':
'SSS
Database',
                                'tools.digest_auth.users':
get_users }
            }


    cherrypy.tree.mount(db, "/", conf)


    # Start CherryPy
    cherrypy.server.quickstart()
    cherrypy.engine.start()

If I remove all the auth configuration except the
conditional stuff
on /sheep/data I get exactly the same results.
Any ideas, or help as to where I look in the server code,
gratefully
received.

Thanks

Pete H


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "cherrypy-users" group.
To post to this group, send email to cherrypy-usersgooglegroups.com
To unsubscribe from this group, send email to
cherrypy-users-unsubscribegooglegroups.com
For more options, visit this group at h
ttp://groups.google.com/group/cherrypy-users?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Problem with digest authentication in RESTful app
country flaguser name
United States
2007-10-19 11:05:38
I should add that this is CherryPy 3.0.2 with Python 2.4 on
Windows XP
Pro and Python 2.5 on Ubuntu 7.04. I've run cherrypy on
localhost on
both machines, and on the Ubuntu machine with the browser on
the
Windows machine. All 3 setups give the same problem

On Oct 19, 4:48 pm, Pete H <pe...ssbg.zetnet.co.uk>
wrote:
> Hello,
>
<snip>
Pete H


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "cherrypy-users" group.
To post to this group, send email to cherrypy-usersgooglegroups.com
To unsubscribe from this group, send email to
cherrypy-users-unsubscribegooglegroups.com
For more options, visit this group at h
ttp://groups.google.com/group/cherrypy-users?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Problem with digest authentication in RESTful app
country flaguser name
United States
2007-10-20 07:58:54


On Oct 19, 5:05 pm, Pete H <pe...ssbg.zetnet.co.uk>
wrote:
> I should add that this is CherryPy 3.0.2 with Python
2.4 on Windows XP
> Pro and Python 2.5 on Ubuntu 7.04. I've run cherrypy on
localhost on
> both machines, and on the Ubuntu machine with the
browser on the
> Windows machine. All 3 setups give the same problem
>
> On Oct 19, 4:48 pm, Pete H <pe...ssbg.zetnet.co.uk> wrote:> Hello,
>
> <snip>
> Pete H

I've now learnt a lot more about CherryPy and python . After
tracing the call stack I now know that the server is
wsgiserver - I
thought wsgi was only used if an additional wsgi app was
added to
cp...

Anyway the problem as far as I can tell is that in my
scenario the
POST request body is never read from the socket, neither is
the socket
flushed, so its still lurking in the socket read buffer when
the next
request comes in. request.respond calls the digest_auth tool
before
reading the body, and digest_auth raises HTTPError which
also doesn't
clean up the request.

I think i should transfer this to a bug unless anyone can
tell me
where I've got it wrong.

Pete H


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the
Google Groups "cherrypy-users" group.
To post to this group, send email to cherrypy-usersgooglegroups.com
To unsubscribe from this group, send email to
cherrypy-users-unsubscribegooglegroups.com
For more options, visit this group at h
ttp://groups.google.com/group/cherrypy-users?hl=en
-~----------~----~----~----~------~----~------~--~---


[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )