diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py index e52879065f2..d4670eabca1 100644 --- a/django/core/handlers/modpython.py +++ b/django/core/handlers/modpython.py @@ -163,3 +163,46 @@ def populate_apache_request(http_response, mod_python_req): def handler(req): # mod_python hooks into this function. return ModPythonHandler()(req) + +def authenhandler(req, **kwargs): + """ + Authentication handler that checks against Django's auth database. + """ + from mod_python import apache + + # mod_python fakes the environ, and thus doesn't process SetEnv. This fixes + # that so that the following import works + os.environ.update(req.subprocess_env) + from django.models.auth import users + + # check for PythonOptions + _str_to_bool = lambda s: s.lower() in '1', 'true', 'on', 'yes' + + options = req.get_options() + permission_name = options.get('DjangoPermissionName', None) + staff_only = _str_to_bool(options.get('DjangoRequireStaffStatus', "on")) + superuser_only = _str_to_bool(options.get('DjangoRequireSuperuserStatus', "off")) + + # check that the username is valid + kwargs = {'username__exact': req.user, 'is_active__exact': True} + if staff_only: + kwargs['is_staff__exact'] = True + if superuser_only: + kwargs['is_superuser__exact'] = True + try: + user = users.get_object(**kwargs) + except users.UserDoesNotExist: + return apache.HTTP_UNAUTHORIZED + + # check the password and any permission given + if user.check_password(req.get_basic_auth_pw()): + if permission_name: + if user.has_perm(permission_name): + return apache.OK + else: + return apache.HTTP_UNAUTHORIZED + else: + return apache.OK + else: + return apache.HTTP_UNAUTHORIZED + \ No newline at end of file diff --git a/docs/apache_auth.txt b/docs/apache_auth.txt new file mode 100644 index 00000000000..bbb2fe091d2 --- /dev/null +++ b/docs/apache_auth.txt @@ -0,0 +1,62 @@ +========================================================= +Authenticating against Django's user database from Apache +========================================================= + +Since keeping multiple authentication databases in sync is a common problem when +dealing with Apache, you can configuring Apache to authenticate against Django's +`authentication system`_ directly. For example, you could: + + * Serve media files directly from Apache only to authenticated users. + + * Authenticate access to a Subversion_ repository against Django users with + a certain permission. + + * Allow certain users to connect to a WebDAV share created with mod_dav_. + +Configuring Apache +================== + +To check against Django's authorization database from a Apache configuration +file, you'll need to use mod_python's ``PythonAuthenHandler`` directive along +with the standard ``Auth*`` and ``Require`` directives:: + + + AuthType basic + AuthName "example.com" + Require valid-user + + SetEnv DJANGO_SETTINGS_MODULE mysite.settings + PythonAuthenHandler django.core.handlers.modpython + + +By default, the authentication handler will limit access to the ``/example/`` +location to users marked as staff members. You can use a set of +``PythonOption`` directives to modify this behavior:: + + ================================ ========================================= + ``PythonOption`` Explanation + ================================ ========================================= + ``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e. + those with the ``is_staff`` flag set) + will be allowed. + + Defaults to ``on``. + + ``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e. + those with the ``is_superuser`` flag set) + will be allowed. + + Defaults to ``off``. + + ``DjangoPermissionName`` The name of a permission to require for + access. See `custom permissions`_ for + more information. + + By default no specific permission will be + required. + ================================ ========================================= + +.. _authentication system: http://www.djangoproject.com/documentation/authentication/ +.. _Subversion: http://subversion.tigris.org/ +.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html +.. _custom permissions: http://www.djangoproject.com/documentation/authentication/#custom-permissions \ No newline at end of file