summaryrefslogtreecommitdiff
path: root/docs/howto/deployment/wsgi/apache-auth.txt
blob: 9246c081e7be91b5530810674e0b9429c51b511e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
=========================================================
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 configure Apache to authenticate against Django's
:doc:`authentication system </topics/auth/index>` directly. This requires Apache
version >= 2.2 and mod_wsgi >= 2.0. For example, you could:

* Serve static/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_.

.. note::
    If you have installed a :ref:`custom User model <auth-custom-user>` 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.

.. _Subversion: http://subversion.tigris.org/
.. _mod_dav: https://httpd.apache.org/docs/2.2/mod/mod_dav.html

Authentication with ``mod_wsgi``
================================

.. 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 one 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 :doc:`Apache with mod_wsgi
</howto/deployment/wsgi/modwsgi>`.

Next, edit your Apache configuration to add a location that you want
only authenticated users to be able to view:

.. code-block:: apache

    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 :doc:`that is created by django-admin startproject
</howto/deployment/wsgi/index>`.

.. admonition:: 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``:

    .. code-block:: apache

        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.

.. _Defining Application Groups: https://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Defining_Application_Groups
.. _access control mechanisms documentation: https://code.google.com/p/modwsgi/wiki/AccessControlMechanisms

Authorization with ``mod_wsgi`` and Django groups
-------------------------------------------------

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:

.. code-block:: apache

    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.

.. code-block:: python

    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.