| 1 | ============================= |
| 2 | Authenticating against REMOTE_USER from Apache |
| 3 | ============================= |
| 4 | |
| 5 | Typically on an intranet, users are already authenticated (e.g. in a Windows domain). |
| 6 | It is possible to let Apache use NTLM to verify that a user is authenticated, and only |
| 7 | allow valid users to enter your website. Apache will set a REMOTE_USER variable containing |
| 8 | the user's username. This can be used to inform django which user is accessing the site. |
| 9 | If the user is not yet in Django's userbase, she can be added automatically. |
| 10 | |
| 11 | Configuring Apache |
| 12 | ============== |
| 13 | |
| 14 | You will need a module that can authenticate using NTLM. |
| 15 | Examples are mod_NTLM or mod_auth_sspi. |
| 16 | Configure Apache to use these to authenticate the user. |
| 17 | An example configuration using mod_auth_sspi looks like this: |
| 18 | |
| 19 | # Add the module: |
| 20 | |
| 21 | LoadModule sspi_auth_module modules/mod_auth_sspi.so |
| 22 | |
| 23 | # Configure the authentication: |
| 24 | |
| 25 | <Location /example/> |
| 26 | AuthName "myIntranet" |
| 27 | AuthType SSPI |
| 28 | SSPIAuth On |
| 29 | SSPIAuthoritative On |
| 30 | SSPIDomain "myDomain" |
| 31 | SSPIOmitDomain On |
| 32 | SSPIUsernameCase "upper" |
| 33 | |
| 34 | Require valid-user |
| 35 | |
| 36 | SetHandler python-program |
| 37 | PythonHandler django.core.handlers.modpython |
| 38 | SetEnv DJANGO_SETTINGS_MODULE your_settings |
| 39 | PythonPath "['d:\\\\websites'] + ['d:\\\\websites\\\\myproject'] + sys.path" |
| 40 | </Location> |
| 41 | |
| 42 | Configuring Django |
| 43 | ============= |
| 44 | |
| 45 | In your settings file, add the RemoteUserAuthMiddleware and the RemoteUserAuthBackend like this: |
| 46 | |
| 47 | Add the middleware AFTER the AuthenticationMiddleware: |
| 48 | |
| 49 | 'django.contrib.auth.middleware.AuthenticationMiddleware', |
| 50 | 'django.contrib.auth.middleware.RemoteUserAuthMiddleware', |
| 51 | |
| 52 | Add the RemoteUserAuthBackend as authentication backend: |
| 53 | AUTHENTICATION_BACKENDS = ( |
| 54 | 'django.contrib.auth.RemoteUserAuthBackend', |
| 55 | ) |
| 56 | |
| 57 | Subclassing the RemoteUserAuthBackend |
| 58 | ============================== |
| 59 | |
| 60 | By default, the RemoteUserAuthBackend will simply add any non existing user to the Django user database. |
| 61 | Since the user was let in by Apache, it is supposed to be a valid user. |
| 62 | However, you may override this behaviour by subclassing the RemoteUserAuthBackend: |
| 63 | |
| 64 | Override the auto-creation of users |
| 65 | ---------------------------------- |
| 66 | The RemoteUserAuthBackend has a function unknown_user(username), which by default creates a new |
| 67 | User object for any user not yet known to Django. It returns the new user object. |
| 68 | If you don't want to auto-create new users, you may override this function to return None. |
| 69 | |
| 70 | Example: |
| 71 | |
| 72 | in settings.py: |
| 73 | |
| 74 | AUTHENTICATION_BACKENDS = ( |
| 75 | 'myproject.utils.MyOwnRemoteUserAuthBackend', |
| 76 | ) |
| 77 | |
| 78 | in myproject.utils: |
| 79 | |
| 80 | from django.contrib.auth.backends import RemoteUserAuthBackend |
| 81 | |
| 82 | class MyOwnRemoteUserAuthBackend(RemoteUserAuthBackend): |
| 83 | def unknown_user(self, username): |
| 84 | return None |
| 85 | |
| 86 | |
| 87 | Configure the properties for the newly created user |
| 88 | ------------------------------------------------- |
| 89 | The RemoteUserAuthBackend has a function configure_user(user), which by default does nothing to |
| 90 | the new user object. |
| 91 | |
| 92 | You could however use this function to set detailed info or permissions on the users (e.g. using info |
| 93 | from an LDAP source). |
| 94 | |
| 95 | Example: |
| 96 | |
| 97 | in settings.py: |
| 98 | |
| 99 | AUTHENTICATION_BACKENDS = ( |
| 100 | 'myproject.utils.MyOwnRemoteUserAuthBackend', |
| 101 | ) |
| 102 | |
| 103 | in myproject.utils: |
| 104 | |
| 105 | from django.contrib.auth.backends import RemoteUserAuthBackend |
| 106 | |
| 107 | class MyOwnRemoteUserAuthBackend(RemoteUserAuthBackend): |
| 108 | def configure_user(self, user): |
| 109 | # put your custom code here |
| 110 | user.last_name = user.username |
| 111 | user.save() |
| 112 | # |
| 113 | return user |