[mod_python] lookup_uri

Graham Dumpleton graham.dumpleton at gmail.com
Sat May 12 02:47:32 EDT 2007


See comments below.

On 12/05/07, Roger Binns <rogerb at rogerbinns.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Graham Dumpleton wrote:
> > You basically didn't want to agree and said:
> >
> > """That is the easy bit :-)  Just copying the authentication response
> > headers from /api will do the trick."""
> >
> > I still believe that you don't quite understand what would happen. Let
> > me see if I can explain it again in a way you can understand.
>
> I really do understand what I am talking about :-)  How about some
> config and code.
>
> <Location /api/v1/widget/>
>   <Limit GET>
>   Require group reader
>   </Limit>
> </Location>
>
> That ensures that Apache requires authentication for the rest service.
> Now this is my code in the handler for /admin which has no directive
> such as the above requiring authentication.
>
> def handler(req):
>    name="foo"
>    # Before generating this page, check they can get info widget
>    sub=req.lookup_method_uri("GET", "/api/v1/widget/"+name)
>    # Copy any authentication to subrequest
>    sub.headers_in["Authorization"]=req.headers_in["Authorization"]
>    # Run the subrequest
>    sub.run()
>    # Was authentication required?
>    if sub.status==401:
>       req.status=401
>
> req.headers_out["WWW-Authenticate"]=sub.headers_out["WWW-Authenticate"]
>       return apache.OK
>    if sub.status!=200:
>       req.status=sub.status
>       ... copy error message or something similar ...
>       return apache.OK

Note though that if using Apache properly, none of the above should be
in handler() in the first place and should be in the authenhandler or
authzhandlers phases instead.

>    # At this point we know that there is permission to read widget
>    ... generate page etc ...
>
> > First off, you said that /admin would have no AuthType/AuthName
> > directives covering that URL in the Apache configuration. Because of
> > this fact, the browser isn't going to be sending any authentication
> > information for that URL. Ie., there will be no Authorization header
> > available to the request handler for the /admin URL.
>
> That is correct.  But the subrequest would return 401 if authentication
> was required and that can be copied into the response for the request so
> the browser will then retry with credentials.
>
> > Your problem as you see it how to check those credentials. The real
> > problem at this point is where are you getting the credentials from if
> > the browser isn't going to send them.
>
> Well it would since I'd send them back from the subrequest as shown above.
>
> > You are skipping this important challenge step by
> > assuming the credentials will be there and simply moving to try and
> > validate them.
>
> Err no, the challenge step is there due to sending 401 and
> WWW-Authenticate header back to the original request.

And I did appreciate you might be doing that, but for the most obvious
cases, at that time I couldn't see the point. If you are going to do
that why not let Apache do all the authentication without this fiddle
and have the AuthType/AuthName/Require directives on /admin in the
first place since it is achieving exactly the same thing.

This is where what you were doing seemed to be getting messy for my
personal tastes in what simply appeared to be an attempt to avoid
duplicating some auth configuration in the Apache configuration files.

> > Where web applications, such as Trac, use a /login URL as a single
> > login point, once they have successfully logged in the user they then
> > use cookies to track the fact that the user is logged in.
>
> Yes.  But those applications also have to implement their own
> authorization system.  I intend to let apache do all that.  For example
> the administrator can do this in the configuration:
>
> <Location /api/v1/widget/>
>   <Limit GET>
>   Require group anyone
>   </Limit>
> </Location>
>
> <Location /api/v1/widget/>
>   <Limit DELETE>
>   Require group admins
>   </Limit>
> </Location>
>
> But then they can be more specific as well:
>
> <Location /api/v1/widget/thelab>
>   <Limit DELETE>
>   Require group labadmins
>   </Limit>
> </Location>

Which is all fine for your separate scripts which access just these
URLs. If your /admin URL needs to only access one of them just
duplicate the Apache auth configuration. If your /admin page needs to
check more than one then you are simply probably getting beyond what
the authorization directives of Apache are good for. You can only go
so far with what Apache directives give you. You may be better off
just doing it all in your own authenhandler and authzhandlers for
mod_python, you certainly shouldn't be trying to put authentication
and authorisation into the response handler phase as you are.

> > If you still disagree, and maybe I am missing something, by what
> > mechanism do you think the credentials will be available in the first
> > place?
>
> The bit you missed is that it is one line of code to copy a status and
> another to copy an Authorization or WWW-Authenticate header :-)
>
> > and dictates various approaches to how one might go about extending
> > mod_python features without actually modifying mod_python.
>
> I guess this looks the closest:
>
>   http://issues.apache.org/jira/browse/MODPYTHON-165
>
> However if I am having to go to the trouble of writing an Apache module
> I may as well just write one that meets my needs exactly and ignore
> mod_python :-(

And I'd probably agree on that last point as mod_python falls quite
short of being a true way of writing Apache modules but using Python
instead of C code and personally I don't see that it will ever be able
to do that. The problem is the way the code base is hand coded is in
the long term going to make it impractical to keep adhoc adding more
and more of the Apache and APR C interfaces especially as the mapping
is a direct mapping but a slight Pythonisation of it. Continually
extending mod_python in this way is certainly not something I am
interested in doing as it would be waste of time and too hard to look
after.

The only practical way of getting a complete Python binding for Apache
and APR C interfaces is to completely start over and use SWIG. At
least that way the bulk of the work is automated and it actually
becomes maintainable. I know SWIGing the interfaces isn't that hard as
I have done it to see what would be involved, just needed to go
through and deal with the special exceptions that require special
handling. Even then it is mostly useless in the context of mod_python
anyway and a whole new base level module for doing Python in Apache is
needed to support it. At this point there hasn't really been anyone
else seriously interested in going that path, at least not to extent
they appeared to be prepared to spend a great deal of time themselves
working on it.

Graham


More information about the Mod_python mailing list