But I think any example functions in the documentation should return apache.AUTH_DENIED by default, with the conditionals checking for success, not failure:

def authbasicprovider(req, user, password):
    if user in users:
        if users[user] == password:
            return apache.AUTH_GRANTED
        return apache.AUTH_USER_NOT_FOUND
    return apache.AUTH_DENIED

Graham Dumpleton (JIRA) wrote:
Add feature to allow mod_python to be an auth provider.

         Key: MODPYTHON-169
         URL: http://issues.apache.org/jira/browse/MODPYTHON-169
     Project: mod_python
        Type: New Feature

Components: core Reporter: Graham Dumpleton Assigned to: Graham Dumpleton

In Apache 2.2, the implementation of authentication has been split into two 
parts. The first is that which handles the specifics of negotiating with a 
client for a specific authentication mechanism type, for example, Basic or 
Digest authentication. The second part is that which handles the specifics of 
verifying the actual users credentials, for example, by looking the user up in 
a dbm database, ldap or some other type of user database.

The second part of this is referred to as the auth provider and in Apache 2.2 
it is possible to hook in additional providers. This means that the any builtin 
support in Apache for Basic and Digest authentication mechanism can be used, 
but the verification could be done by some arbitrary user code. Such 
verification could be done in Python, if mod_python allowed one to define the 
necessary auth provider hooks.

To this end, proposed that mod_python be extended such that when using Apache 
2.2, that it is possible to say:

  AuthType Basic
  AuthName "Restricted Files"
  AuthBasicProvider mod_python
  PythonAuthBasicProvider somemodule


  AuthType Digest
  AuthName "Restricted Files"
  AuthDigestProvider mod_python
  PythonAuthDigestProvider somemodule

That is, by specifying mod_python in conjunction with AuthBasicProvider  or 
AuthDigestProvider directives, it triggers mod_python to be given option of 
satisfying need to perform verification of user credentials. The function to be 
called for each being given by the PythonAuthBasicProvider and 
PythonAuthDigestProvider respectively.

The argument to these directives would be a module name, in which case a function of the name 
"authbasicprovider" or "authdigestprovider" will be expected to exist. If 
wanting to specify a particular module, like in handler directives, would also be possible to say:

  PythonAuthBasicProvider somemodule::check_password
  PythonAuthDigestProvider somemodule::get_realm_hash

Note that the prototype of the function for each would not be like existing 
handlers and is different in each case. For the Basic auth mechanism, an 
example function would be:

  users = { ... }

  def authbasicprovider(req, user, password):

    # could consult req.auth_name() to get realm

    if user not in users:
      return apache.AUTH_USER_NOT_FOUND

    # assuming passwords are stored in clear text

    if users[user] != password:
      return apache.AUTH_DENIED

  return apache.AUTH_GRANTED

Exceptions would be translated into apache.AUTH_GENERAL_ERROR, or function 
could explicitly return it. Could also allow explicit exception of type 
apache.SERVER_RETURN like in handlers but where argument is auth values.

For Digest authentication, function would be:

  def authdigestprovider(req, user, realm):

    # could select database based on 'realm'

    if user not in users:
      return None

    # assuming passwords are stored in clear text

    return md5.new("%s:%s:%s" % (user, realm, users[user])).hexdigest()

In this later function, return None indicates apache.AUTH_USER_NOT_FOUND. An 
apache.SERVER_RETURN exception could also be used with that value as argument. 
Returning of an actual string would imply apache.AUTH_USER_FOUND. Unexpected 
exceptions taken as apache.AUTH_GENERAL_ERROR, or could be raised explicitly 
using apache.SERVER_RETURN exception.

What all this would mean is that you would never need to write an authenhandler 
again using mod_python, as you could rely on any type of authenhandler builtin 
to Apache or as as supported by some third party Apache module. All you would 
need to do is supply the auth provider or Basic or Digest authentication as 
necessary to support verification of the user.

Reply via email to