Ticket #10809: modwsgi_auth_handler.4.diff
File modwsgi_auth_handler.4.diff, 9.1 KB (added by , 13 years ago) |
---|
-
docs/howto/apache-auth.txt
2 2 Authenticating against Django's user database from Apache 3 3 ========================================================= 4 4 5 .. warning::6 7 Support for mod_python has been deprecated within Django. At that8 time, this method of authentication will no longer be provided by9 Django. The community is welcome to offer its own alternate10 solutions using WSGI middleware or other approaches.11 12 5 Since keeping multiple authentication databases in sync is a common problem when 13 6 dealing with Apache, you can configuring Apache to authenticate against Django's 14 7 :doc:`authentication system </topics/auth>` directly. For example, you … … 24 17 .. _Subversion: http://subversion.tigris.org/ 25 18 .. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html 26 19 27 Configuring Apache 28 ================== 20 Authentication with mod_wsgi 21 ============================ 29 22 30 To check against Django's authorization database from a Apache configuration 31 file, you'll need to use mod_python's ``PythonAuthenHandler`` directive along 23 Make sure that mod_wsgi is installed and activated and that you have 24 followed the steps to setup 25 :doc:`Apache with mod_wsgi <deployment/wsgi/modwsgi>` 26 27 Next, edit your Apache configuration to add a path that you want 28 only authenticated users to be able to view: 29 30 .. code-block:: apache 31 32 WSGIScriptAlias / /path/to/mysite/config/mysite.wsgi 33 34 WSGIProcessGroup %{GLOBAL} 35 WSGIApplicationGroup django 36 37 <Location "/secret"> 38 AuthType Basic 39 AuthName "Top Secret" 40 Require valid-user 41 AuthBasicProvider wsgi 42 WSGIAuthUserScript /path/to/mysite/config/mysite.wsgi 43 </Location> 44 45 The ``WSGIAuthUserScript`` directive tells mod_wsgi to execute the 46 ``check_password`` function in that script passing the user name and 47 password that it receives from the prompt. In this example, 48 the ``WSGIAuthUserScript`` is the same as the ``WSGIScriptAlias`` that 49 defines your application. 50 51 .. admonition:: Using Apache 2.2 with authentication 52 53 Make sure that ``mod_auth_basic`` and ``mod_authz_user`` are loaded. 54 55 These might be compiled statically into Apache, or you might need to use 56 LoadModule to load them dynamically in your ``httpd.conf``: 57 58 .. code-block:: apache 59 60 LoadModule auth_basic_module modules/mod_auth_basic.so 61 LoadModule authz_user_module modules/mod_authz_user.so 62 63 Finally, edit your WSGI auth script ``mysite.wsgi`` to tie Apache's 64 authentication to yoursite's users: 65 66 .. code-block:: python 67 68 import os 69 import sys 70 71 os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' 72 73 from django.contrib.auth.handlers.modwsgi import check_user 74 75 from django.core.handlers.wsgi import WSGIHandler 76 application = WSGIHandler() 77 78 79 Requests beginning with ``/secret/`` will now require a user to authenticate. 80 81 The mod_wsgi `access control mechanisms documentation`_ provides additional 82 details and information about alternative methods of authentication. 83 84 .. _access control mechanisms documentation: http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms 85 86 Authorization with mod_wsgi and Django groups 87 --------------------------------------------- 88 89 In addition, mod_wsgi also provides functionality to restrict a particular 90 location to members of a group. 91 92 In this case, the Apache configuration should look like this: 93 94 .. code-block:: apache 95 96 WSGIScriptAlias / /path/to/mysite/config/mysite.wsgi 97 98 WSGIProcessGroup %{GLOBAL} 99 WSGIApplicationGroup django 100 101 <Location "/secret"> 102 AuthType Basic 103 AuthName "Top Secret" 104 AuthBasicProvider wsgi 105 WSGIAuthUserScript /path/to/mysite/config/mysite.wsgi 106 WSGIAuthGroupScript /path/to/mysite/config/mysite.wsgi 107 Require group secret-agents 108 Require valid-user 109 </Location> 110 111 Because of the ``WSGIAuthGroupScript`` directive, the same WSGI auth script 112 ``mysite.wsgi`` must also import the method ``groups_for_user`` which 113 returns a list of the user's groups. 114 115 .. code-block:: python 116 117 from django.contrib.auth.handlers.modwsgi import check_user, groups_for_user 118 119 Requests for ``/secret/`` will now also require a user to a member of the 120 "secret-agents" group. 121 122 Authentication with mod_python 123 ============================== 124 125 .. warning:: 126 127 Support for mod_python has been deprecated within Django. At that 128 time, this method of authentication will no longer be provided by 129 Django. The community is welcome to offer its own alternate 130 solutions using WSGI middleware or other approaches. 131 132 To check against Django's authorization database from mod_python, 133 you'll need to use mod_python's ``PythonAuthenHandler`` directive along 32 134 with the standard ``Auth*`` and ``Require`` directives: 33 135 34 136 .. code-block:: apache … … 89 191 PythonAuthenHandler django.contrib.auth.handlers.modpython 90 192 </Location> 91 193 92 By default, the authentication handler will limit access to the ``/example/``93 location to users marked as staff members. You can use a set of194 By default, the mod_python authentication handler will limit access to the 195 ``/example/`` location to users marked as staff members. You can use a set of 94 196 ``PythonOption`` directives to modify this behavior: 95 197 96 198 ================================ ========================================= -
django/contrib/auth/handlers/modwsgi.py
1 from django.contrib.auth.models import User 2 from django import db 3 4 def check_password(environ, username, password): 5 """ 6 Authenticates against Django's auth database 7 """ 8 9 db.reset_queries() 10 11 try: 12 # verify the user exists 13 try: 14 user = User.objects.get(username=username, is_active=True) 15 except User.DoesNotExist: 16 return None 17 18 # verify the password for the given user 19 if user.check_password(password): 20 return True 21 else: 22 return False 23 finally: 24 db.close_connection() 25 26 def groups_for_user(environ, username): 27 """ 28 Authorizes a user based on groups 29 """ 30 31 db.reset_queries() 32 33 try: 34 try: 35 user = User.objects.get(username=username, is_active=True) 36 except User.DoesNotExist: 37 return [] 38 39 return [group.name.encode('utf-8') for group in user.groups.all()] 40 finally: 41 db.close_connection() -
django/contrib/auth/tests/__init__.py
17 17 from django.contrib.auth.tests.views import (AuthViewNamedURLTests, 18 18 PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest, 19 19 LoginURLSettings) 20 from django.contrib.auth.tests.handlers import ModWsgiHandlerTestCase 20 21 21 22 # The password for the fixture data users is 'password' -
django/contrib/auth/tests/handlers.py
1 from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user 2 from django.contrib.auth.models import User, Group 3 from django.test import TestCase 4 5 class ModWsgiHandlerTestCase(TestCase): 6 """ 7 Tests for the mod_wsgi authentication handler 8 """ 9 10 def setUp(self): 11 user1 = User.objects.create_user('test', 'test@example.com', 'test') 12 user2 = User.objects.create_user('test1', 'test1@example.com', 'test1') 13 14 group = Group.objects.create(name='test_group') 15 user1.groups.add(group) 16 17 18 def testCheckPassword(self): 19 """ 20 Verify that check_password returns the correct values as per 21 http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Authentication_Provider 22 """ 23 24 # User not in database 25 self.assertTrue(check_password({}, 'unknown', '') is None) 26 27 # Valid user with correct password 28 self.assertTrue(check_password({}, 'test', 'test')) 29 30 # Valid user with incorrect password 31 self.assertFalse(check_password({}, 'test', 'incorrect')) 32 33 def testGroupsForUser(self): 34 """ 35 Check that groups_for_user returns correct values as per 36 http://code.google.com/p/modwsgi/wiki/AccessControlMechanisms#Apache_Group_Authorisation 37 """ 38 39 # User not in database 40 self.assertEqual(groups_for_user({}, 'unknown'), []) 41 42 self.assertEqual(groups_for_user({}, 'test'), ['test_group']) 43 self.assertEqual(groups_for_user({}, 'test2'), [])