Issue Details (XML | Word | Printable)

Key: MODPYTHON-47
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Minor Minor
Assignee: Graham Dumpleton
Reporter: Graham Dumpleton
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
mod_python

Digest Authorization header causes bad request error.

Created: 21/Apr/05 01:48 PM   Updated: 02/Apr/07 11:19 AM
Return to search
Component/s: publisher
Affects Version/s: 3.1.4
Fix Version/s: 3.3.1

Time Tracking:
Not Specified

File Attachments:
  Size
File Licensed for inclusion in ASF works MP47_20060307_grahamd_1.diff 2006-03-07 07:19 PM Graham Dumpleton 0.8 kB
File Licensed for inclusion in ASF works MP47_20060309_grahamd_2.diff 2006-03-09 08:40 AM Graham Dumpleton 2 kB

Resolution Date: 10/Mar/06 06:20 PM


 Description  « Hide
If Apache is used to perform authentication, the Authorization header still gets
passed through to mod_python.publisher. Unfortunately, mod_python.publisher
authentication code in process_auth() will attempt to decode the contents of the
Authorization header even if there are no __auth__ or __access__ hooks defined
for authentication and access control within the published code itself.

The consequence of this is that if Digest authentication is used for AuthType
at level of Apache authentication, the process_auth() code will raise a bad request
error as it assumes Authorization header is always in format for Basic authentication
type and when it can't decode it, it raises an error.

What should happen is that any decoding of Authorization should only be done
if there is a __auth__ or __access__ hook that actually requires it. That way, if some
one uses Digest authentication at Apache configuration file level, provided that no
__auth__ or __access__ hooks are provided, there wouldn't be a problem.

See:

  http://www.modpython.org/pipermail/mod_python/2005-April/017911.html
  http://www.modpython.org/pipermail/mod_python/2005-April/017912.html

for additional information.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Graham Dumpleton added a comment - 22/Apr/05 07:29 AM
This issue was also raised a few years ago on the mailing list. Relevant mailing list
post at the time with suggested fix was:

  http://www.modpython.org/pipermail/mod_python/2002-September/013071.html

The suggested fix at the time was to set user,passwd to None,None with similar
check as initially suggested this time round.

In vampire::publisher where similar problem existed, was found to be better to
defer parsing of Authorization until determined it was needed though as it then
mean't you got a hard error if actually trying to use __auth__ or __access__ instead
of it being silently ignored. Ie., error would occur still where you were trying to
mix two different authorisation types.

Graham Dumpleton added a comment - 23/Nov/05 09:31 AM
As usual there is nearly always a way to fudge things. You could still use Apache HTTP digest authentication (managed by Apache) and still use mod_python.publisher by having an authenhandler() or earlier content handler which deleted the "Authorization" header so that mod_python.publisher didn't find it and therefore didn't barf.

  def authenhandler(req):

    if req.headers_in.has_key("Authorization"):
       del req.headers_in["Authorization"]

    ... etc.

I haven't tried this, but it should work.

Graham Dumpleton added a comment - 14/Feb/06 09:04 AM
The simplest way of fixing this problem may be that after changes related to MODPYTHON-124 are made that the publisher simply not try and authenticate users if req.ap_auth_type is not None.

In other words, if AuthType directive has been defined assume that something else is handling authentication and that publisher doesn't have to worry about it. This will mean publisher will not redundantly decode authorisation header if AuthType was Basic and was being handled explicitly by mod_auth in Apache and outside of the publisher.

Thus, insert at start of process_auth():

  if req.ap_auth_type:
    return realm, user, passwd

Graham Dumpleton added a comment - 07/Mar/06 07:19 PM
Attached "MP47_20060307_grahamd_1.diff" with proposed patch. Feedback on this one appreciated.

Jim Gallacher added a comment - 09/Mar/06 08:07 AM
I'm don't really like this patch (MP47_20060307_grahamd_1.diff) as it bypasses any authorization or access checks in the object being published.

Authentication != authorization

I'm not sure what the answer is, but I think we all know that the problem lies in the fact that publisher is too tightly bound to basic authentication.

Graham Dumpleton added a comment - 09/Mar/06 08:40 AM
Attached alternate suggested fix as "MP47_20060309_grahamd_2.diff".

I should have just done it this way to begin with.

What this does is simply not try and do anything with the Authorization header unless either __auth__ or __access_ are actually found. Ie., the fix I originally described, rather than my latter obsession with req.ap_auth_type.

This means that if one has __auth__ or __access__ and Apache configuration still uses digest authentication it will fail. But if one knows one is using digest authentication support in mod_auth, you would not be using the publisher auth support anyway as they would conflict.

I agree that authentication should not be part of publisher, but can't do anything about that now. Apache has a really good concept of phases yet just about everything merely uses mod_python as a hopping off point at content handler phase and does everything in that one phase. :-(

Jim Gallacher added a comment - 10/Mar/06 07:27 AM
The second patch is likely the best compromise.

I think part of the problem with process_auth() is the uncertainty of meaning associated with auth and __auth__. Does it mean authenticate or authorize? If it's authorize, then there is no reason to call __auth__ with the password. Likewise, you shouldn't need the user name when calling __access__. One could certainly come up with access rules which are not tied to a specific user.

Maybe we should consider refactoring process_auth() to look for 2 new attributes such as __authen__ and __author__, and deprecate the use of __auth__. If somebody wants to do authentication in publisher then their code would be completely responsible for returning either a user or raising an error. (Further discussion of this should be shifted out of this particular issue).