Ticket #689: 689.diff

File 689.diff, 8.0 KB (added by guettli, 7 years ago)
  • django/contrib/auth/backends.py

     
    6868            return User.objects.get(pk=user_id)
    6969        except User.DoesNotExist:
    7070            return None
     71
     72class RemoteUserAuthBackend:
     73
     74    def authenticate(self, username, password=None):
     75        """
     76        Authenticate user - RemoteUserAuth middleware passes REMOTE_USER
     77        as username.
     78        """
     79        if password is not None:
     80            return None
     81        user = None
     82        if username:
     83            username = self.parse_user(username)
     84            try:
     85                user = User.objects.get(username=username)
     86            except User.DoesNotExist:
     87                user = self.unknown_user(username)
     88                user = self.configure_user(user)
     89        return user
     90
     91    def parse_user(self, username):
     92        """ Parse the provided username.
     93        Override this method if you need to do special things with the
     94        username, like stripping @realm or cleaning something like
     95        cn=x,dc=sas,etc.
     96        """
     97        return username
     98
     99    def get_user(self, user_id):
     100        try:
     101            return User.objects.get(pk=user_id)
     102        except User.DoesNotExist:
     103            return None
     104
     105    def unknown_user(self, username):
     106        # Auto-create user
     107        user = User.objects.create_user(username, '')
     108        user.is_staff = False
     109        user.save()
     110        return user
     111
     112    def configure_user(self, user):
     113        """ Configure a user after login.
     114        i.e: to read group membership from LDAP and so on.
     115        """
     116        return user
  • django/contrib/auth/middleware.py

     
    1010        assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
    1111        request.__class__.user = LazyUser()
    1212        return None
     13
     14class RemoteUserAuthMiddleware(object):
     15    def process_request(self, request):
     16        from django.contrib.auth import authenticate, login
     17        # AuthenticationMiddleware is required to create request.user
     18        error = """The Django RemoteUserAuth middleware requires authentication middleware to be installed. Edit your MIDDLEWARE_CLASSES
     19setting to insert 'django.contrib.auth.middleware.AuthenticationMiddleware' *before* the RemoteUserMiddleware class."""
     20        assert hasattr(request, 'user'), error
     21        if request.user.is_anonymous():
     22            user = None
     23            try:
     24                user = authenticate(username=request.META['REMOTE_USER'])
     25            except KeyError:
     26                pass # No remote user available
     27            if user is not None:
     28                request.user = user    # set request.user to the authenticated user
     29                login(request, user)   # auto-login the user to Django
     30        return None
  • django/contrib/auth/tests.py

     
    3535[]
    3636>>> a.user_permissions.all()
    3737[]
    38 """
    39  Kein Zeilenvorschub am Ende der Datei
     38"""
     39
     40import os
     41import unittest
     42from doctest import DocTestSuite
     43from django.contrib.auth.models import User
     44from django.contrib.auth.backends import RemoteUserAuthBackend
     45from django.test.client import Client
     46from django.conf import settings
     47
     48class HttpAuthTest(unittest.TestCase):
     49    def setUp(self):
     50        self.extra_headers = {'REMOTE_USER': 'iamnotanuser'}
     51        self.curr_middleware = settings.MIDDLEWARE_CLASSES
     52        self.curr_auth = settings.AUTHENTICATION_BACKENDS
     53
     54        settings.MIDDLEWARE_CLASSES +=\
     55            ('django.contrib.auth.middleware.RemoteUserAuthMiddleware', )
     56        settings.AUTHENTICATION_BACKENDS =\
     57            ('django.contrib.auth.backends.RemoteUserAuthBackend',)
     58
     59    def testRemoteUserIsRespected(self):
     60        c = Client()
     61        extra_headers = {'REMOTE_USER': 'iamnotanuser'}
     62        res = c.get('/', {}, **self.extra_headers)
     63
     64        u = User.objects.get(username='iamnotanuser')
     65        # wow, the user was created! this works.
     66
     67    def tearDown(self):
     68        # Restore settings to avoid breaking other tests.
     69        settings.MIDDLEWARE_CLASSES = self.curr_middleware
     70        settings.AUTHENTICATION_BACKENDS = self.curr_auth
     71
     72
     73def suite():
     74    doctest_suite = DocTestSuite()
     75    http_auth_suite = unittest.TestLoader().loadTestsFromTestCase(HttpAuthTest)
     76    return unittest.TestSuite([doctest_suite, http_auth_suite])
  • docs/auth_remote_user.txt

     
     1======================================================
     2Authenticating against REMOTE_USER from the Web Server
     3======================================================
     4
     5Typically on intranet sites users are already authenticated (i.e. in a Windows
     6domain) by the web server (i.e. using IIS Integrated Authentication).
     7
     8When the web server takes care of authentication it sets the ``REMOTE_USER`` HTTP
     9header for use in the underlying application (i.e. Django). Then it's up to
     10this application take care of the authorization.
     11
     12Django brings all you need to make use of the ``REMOTE_USER`` header bringing you
     13one step further to single sign-on on enterprise infrastucure!
     14
     15We assume that you have already configured your web server to authenticate
     16users, maybe with mod_auth_sspi in Apache, Integrated Authentication in IIS
     17and so on.
     18
     19Configuring Django
     20==================
     21
     22First of all, you must add the ``RemoteUserAuthMiddleware`` just **after**
     23(never before) ``AuthenticationMiddleware``.
     24
     25If you want more control, you can inherited from ``RemoteUserAuthBackend`` and
     26override a few methods:
     27
     28   * ``parse_user``: Should cleanup ``REMOTE_USER`` (i.e. strip @realm from
     29     it). It takes the ``username`` as argument, and must return the cleaned
     30     ``username``.
     31   * ``unkown_user``: Should create and return a ``User`` object, will be
     32     called when a ``User`` object does not exist for ``REMOTE_USER``. Takes
     33     ``username`` as it's only argument.
     34   * ``configure_user``: Will be called after ``unkown_user`` so you can
     35     configure the recently created ``User`` object (in case you did not want
     36     to override ``unkown_user``. Takes the ``User`` instance as an argument.
     37     Should also return the ``User`` instance that represents the User.
     38
     39
     40Examples:
     41
     42    settings.py::
     43
     44        MIDDLEWARE_CLASSES = (
     45            'django.contrib.auth.middleware.AuthenticationMiddleware',
     46            'django.contrib.auth.middleware.RemoteUserAuthMiddleware',
     47            ...
     48            )
     49           
     50        AUTHENTICATION_BACKENDS = (
     51            'django.contrib.auth.backends.RemoteUserAuthBackend',
     52        )
  • docs/authentication.txt

     
    10201020database-based scheme, or you can use the default system in tandem with other
    10211021systems.
    10221022
     1023.. admonition:: Handling authentication at the web server
     1024
     1025    There's a very specific situation/scenario in which you want to handle
     1026    authentication at the web server's level (i.e. standard HTTP AUTH) and want
     1027    Django to honour this authentication. This is covered in a separate page:
     1028    `Authenticating against REMOTE_USER from the Web Server`_
     1029
     1030.. _Authenticating against REMOTE_USER from the Web Server: ../auth_remote_user/
     1031
    10231032Specifying authentication backends
    10241033----------------------------------
    10251034
Back to Top