Since keeping multiple authentication databases in sync is a common problem when dealing with Apache, you can configure Apache to authenticate against Django’s authentication system directly. This requires Apache version >= 2.2 and mod_wsgi >= 2.0. For example, you could:
Note
If you have installed a custom User model and want to use this default auth handler, it must support an is_active attribute. If you want to use group based authorization, your custom user must have a relation named ‘groups’, referring to a related object that has a ‘name’ field. You can also specify your own custom mod_wsgi auth handler if your custom cannot conform to these requirements.
Note
The use of WSGIApplicationGroup %{GLOBAL} in the configurations below presumes that your Apache instance is running only one Django application. If you are running more than Django application, please refer to the Defining Application Groups section of the mod_wsgi docs for more information about this setting.
Make sure that mod_wsgi is installed and activated and that you have followed the steps to setup Apache with mod_wsgi.
Next, edit your Apache configuration to add a location that you want only authenticated users to be able to view:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
WSGIProcessGroup %{GLOBAL}
WSGIApplicationGroup %{GLOBAL}
<Location "/secret">
AuthType Basic
AuthName "Top Secret"
Require valid-user
AuthBasicProvider wsgi
WSGIAuthUserScript /path/to/mysite.com/mysite/wsgi.py
</Location>
The WSGIAuthUserScript directive tells mod_wsgi to execute the check_password function in specified wsgi script, passing the user name and password that it receives from the prompt. In this example, the WSGIAuthUserScript is the same as the WSGIScriptAlias that defines your application that is created by django-admin.py startproject.
Using Apache 2.2 with authentication
Make sure that mod_auth_basic and mod_authz_user are loaded.
These might be compiled statically into Apache, or you might need to use LoadModule to load them dynamically in your httpd.conf:
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authz_user_module modules/mod_authz_user.so
Finally, edit your WSGI script mysite.wsgi to tie Apache’s authentication to your site’s authentication mechanisms by importing the check_password function:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
from django.contrib.auth.handlers.modwsgi import check_password
from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()
Requests beginning with /secret/ will now require a user to authenticate.
The mod_wsgi access control mechanisms documentation provides additional details and information about alternative methods of authentication.
mod_wsgi also provides functionality to restrict a particular location to members of a group.
In this case, the Apache configuration should look like this:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIProcessGroup %{GLOBAL}
WSGIApplicationGroup %{GLOBAL}
<Location "/secret">
AuthType Basic
AuthName "Top Secret"
AuthBasicProvider wsgi
WSGIAuthUserScript /path/to/mysite.com/mysite/wsgi.py
WSGIAuthGroupScript /path/to/mysite.com/mysite/wsgi.py
Require group secret-agents
Require valid-user
</Location>
To support the WSGIAuthGroupScript directive, the same WSGI script mysite.wsgi must also import the groups_for_user function which returns a list groups the given user belongs to.
from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user
Requests for /secret/ will now also require user to be a member of the “secret-agents” group.
Jul 20, 2015