1. ==============================================================
    
  2. How to authenticate against Django's user database from Apache
    
  3. ==============================================================
    
  4. 
    
  5. Since keeping multiple authentication databases in sync is a common problem when
    
  6. dealing with Apache, you can configure Apache to authenticate against Django's
    
  7. :doc:`authentication system </topics/auth/index>` directly. This requires Apache
    
  8. version >= 2.2 and mod_wsgi >= 2.0. For example, you could:
    
  9. 
    
  10. * Serve static/media files directly from Apache only to authenticated users.
    
  11. 
    
  12. * Authenticate access to a Subversion_ repository against Django users with
    
  13.   a certain permission.
    
  14. 
    
  15. * Allow certain users to connect to a WebDAV share created with mod_dav_.
    
  16. 
    
  17. .. note::
    
  18.     If you have installed a :ref:`custom user model <auth-custom-user>` and
    
  19.     want to use this default auth handler, it must support an ``is_active``
    
  20.     attribute. If you want to use group based authorization, your custom user
    
  21.     must have a relation named 'groups', referring to a related object that has
    
  22.     a 'name' field. You can also specify your own custom mod_wsgi
    
  23.     auth handler if your custom cannot conform to these requirements.
    
  24. 
    
  25. .. _Subversion: https://subversion.apache.org/
    
  26. .. _mod_dav: https://httpd.apache.org/docs/2.2/mod/mod_dav.html
    
  27. 
    
  28. Authentication with ``mod_wsgi``
    
  29. ================================
    
  30. 
    
  31. .. note::
    
  32. 
    
  33.     The use of ``WSGIApplicationGroup %{GLOBAL}`` in the configurations below
    
  34.     presumes that your Apache instance is running only one Django application.
    
  35.     If you are running more than one Django application, please refer to the
    
  36.     `Defining Application Groups`_ section of the mod_wsgi docs for more
    
  37.     information about this setting.
    
  38. 
    
  39. Make sure that mod_wsgi is installed and activated and that you have
    
  40. followed the steps to set up :doc:`Apache with mod_wsgi
    
  41. </howto/deployment/wsgi/modwsgi>`.
    
  42. 
    
  43. Next, edit your Apache configuration to add a location that you want
    
  44. only authenticated users to be able to view:
    
  45. 
    
  46. .. code-block:: apache
    
  47. 
    
  48.     WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
    
  49.     WSGIPythonPath /path/to/mysite.com
    
  50. 
    
  51.     WSGIProcessGroup %{GLOBAL}
    
  52.     WSGIApplicationGroup %{GLOBAL}
    
  53. 
    
  54.     <Location "/secret">
    
  55.         AuthType Basic
    
  56.         AuthName "Top Secret"
    
  57.         Require valid-user
    
  58.         AuthBasicProvider wsgi
    
  59.         WSGIAuthUserScript /path/to/mysite.com/mysite/wsgi.py
    
  60.     </Location>
    
  61. 
    
  62. The ``WSGIAuthUserScript`` directive tells mod_wsgi to execute the
    
  63. ``check_password`` function in specified wsgi script, passing the user name and
    
  64. password that it receives from the prompt. In this example, the
    
  65. ``WSGIAuthUserScript`` is the same as the ``WSGIScriptAlias`` that defines your
    
  66. application :doc:`that is created by django-admin startproject
    
  67. </howto/deployment/wsgi/index>`.
    
  68. 
    
  69. .. admonition:: Using Apache 2.2 with authentication
    
  70. 
    
  71.     Make sure that ``mod_auth_basic`` and ``mod_authz_user`` are loaded.
    
  72. 
    
  73.     These might be compiled statically into Apache, or you might need to use
    
  74.     LoadModule to load them dynamically in your ``httpd.conf``:
    
  75. 
    
  76.     .. code-block:: apache
    
  77. 
    
  78.         LoadModule auth_basic_module modules/mod_auth_basic.so
    
  79.         LoadModule authz_user_module modules/mod_authz_user.so
    
  80. 
    
  81. Finally, edit your WSGI script ``mysite.wsgi`` to tie Apache's authentication
    
  82. to your site's authentication mechanisms by importing the ``check_password``
    
  83. function::
    
  84. 
    
  85.     import os
    
  86. 
    
  87.     os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
    
  88. 
    
  89.     from django.contrib.auth.handlers.modwsgi import check_password
    
  90. 
    
  91.     from django.core.handlers.wsgi import WSGIHandler
    
  92.     application = WSGIHandler()
    
  93. 
    
  94. 
    
  95. Requests beginning with ``/secret/`` will now require a user to authenticate.
    
  96. 
    
  97. The mod_wsgi `access control mechanisms documentation`_ provides additional
    
  98. details and information about alternative methods of authentication.
    
  99. 
    
  100. .. _Defining Application Groups: https://modwsgi.readthedocs.io/en/develop/user-guides/configuration-guidelines.html#defining-application-groups
    
  101. .. _access control mechanisms documentation: https://modwsgi.readthedocs.io/en/develop/user-guides/access-control-mechanisms.html
    
  102. 
    
  103. Authorization with ``mod_wsgi`` and Django groups
    
  104. -------------------------------------------------
    
  105. 
    
  106. mod_wsgi also provides functionality to restrict a particular location to
    
  107. members of a group.
    
  108. 
    
  109. In this case, the Apache configuration should look like this:
    
  110. 
    
  111. .. code-block:: apache
    
  112. 
    
  113.     WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
    
  114. 
    
  115.     WSGIProcessGroup %{GLOBAL}
    
  116.     WSGIApplicationGroup %{GLOBAL}
    
  117. 
    
  118.     <Location "/secret">
    
  119.         AuthType Basic
    
  120.         AuthName "Top Secret"
    
  121.         AuthBasicProvider wsgi
    
  122.         WSGIAuthUserScript /path/to/mysite.com/mysite/wsgi.py
    
  123.         WSGIAuthGroupScript /path/to/mysite.com/mysite/wsgi.py
    
  124.         Require group secret-agents
    
  125.         Require valid-user
    
  126.     </Location>
    
  127. 
    
  128. To support the ``WSGIAuthGroupScript`` directive, the same WSGI script
    
  129. ``mysite.wsgi`` must also import the ``groups_for_user`` function which
    
  130. returns a list groups the given user belongs to.
    
  131. 
    
  132. .. code-block:: python
    
  133. 
    
  134.     from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user
    
  135. 
    
  136. Requests for ``/secret/`` will now also require user to be a member of the
    
  137. "secret-agents" group.