Index: django/contrib/auth/backends.py
===================================================================
--- django/contrib/auth/backends.py	(revision 6820)
+++ django/contrib/auth/backends.py	(working copy)
@@ -68,3 +68,49 @@
             return User.objects.get(pk=user_id)
         except User.DoesNotExist:
             return None
+
+class RemoteUserAuthBackend(ModelBackend):
+
+    def __init__(self):
+        if self.__class__ == RemoteUserAuthBackend:
+            raise TypeError, "You must create your own class derived\
+from Remote UserAuthBackend in order to use it."
+
+    def authenticate(self, username, password=None):
+        """
+        Authenticate user - RemoteUserAuth middleware passes REMOTE_USER
+        as username. password param is not used, just added in case :)
+        """
+        user = None
+        if username:
+            username = self.parse_user(username)
+            try:
+                user = User.objects.get(username=username)
+            except User.DoesNotExist:
+                user = self.unknown_user(username)
+                user = self.configure_user(user)
+        return user
+
+    def parse_user(self, username):
+        """ Parse the provided username.
+        Override this method if you need to do special things with the
+        username, like stripping @realm or cleaning something like
+        cn=x,dc=sas,etc.
+        """
+        return username
+
+    def unknown_user(self, username):
+        # Auto-create user
+        password = User.objects.make_random_password()
+        user = User.objects.create_user(username, '', password)
+        user.is_staff = False
+        user.set_unusable_password()
+        user.save()
+        return user
+
+    def configure_user(self, user):
+        """ Configure a user after login.
+        i.e: to read group membership from LDAP and so on.
+        """
+        return user
+
Index: django/contrib/auth/middleware.py
===================================================================
--- django/contrib/auth/middleware.py	(revision 6820)
+++ django/contrib/auth/middleware.py	(working copy)
@@ -10,3 +10,21 @@
         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'."
         request.__class__.user = LazyUser()
         return None
+
+class RemoteUserAuthMiddleware(object):
+    def process_request(self, request):
+        from django.contrib.auth import authenticate, login
+        # AuthenticationMiddleware is required to create request.user
+        error = """The Django RemoteUserAuth middleware requires authentication middleware to be installed. Edit your MIDDLEWARE_CLASSES
+setting to insert 'django.contrib.auth.middleware.AuthenticationMiddleware' *before* the RemoteUserMiddleware class."""
+        assert hasattr(request, 'user'), error
+        if request.user.is_anonymous():
+            user = None
+            try:
+                user = authenticate(username=request.META['REMOTE_USER'])
+            except KeyError:
+                pass # No remote user available
+            if user is not None:
+                request.user = user    # set request.user to the authenticated user
+                login(request, user)   # auto-login the user to Django
+        return None
Index: django/contrib/auth/tests.py
===================================================================
--- django/contrib/auth/tests.py	(revision 6820)
+++ django/contrib/auth/tests.py	(working copy)
@@ -1,3 +1,51 @@
+import os
+import unittest
+from django.contrib.auth.models import User
+from django.contrib.auth.backends import RemoteUserAuthBackend
+from django.test.client import Client
+from django.conf import settings
+
+class SimpleDerivedBackend(RemoteUserAuthBackend):
+    pass
+
+class HttpAuthTest(unittest.TestCase):
+    def setUp(self):
+        self.extra_headers = {'REMOTE_USER': 'iamnotanuser'}
+        self.curr_middleware = settings.MIDDLEWARE_CLASSES
+        self.curr_auth = settings.AUTHENTICATION_BACKENDS
+
+        settings.MIDDLEWARE_CLASSES +=\
+            ('django.contrib.auth.middleware.RemoteUserAuthMiddleware', )
+        settings.AUTHENTICATION_BACKENDS =\
+            ('django.contrib.auth.tests.SimpleDerivedBackend',)
+
+    def testBackendMustBeDerived(self):
+        """
+        HttpAuthTest.testBackendMustBeDerived: RemoteUserAuthBackend cannot be
+        used without being inherited by another class.
+        """
+        # RemoteUserAuthBackend cannot be instantiated!
+        self.assertRaises(TypeError, RemoteUserAuthBackend)
+
+        # Check that it won't work on a request.
+        settings.AUTHENTICATION_BACKENDS =\
+            ('django.contrib.auth.backends.RemoteUserAuthBackend',)
+        c = Client()
+        self.assertRaises(TypeError, c.get ,'/', {}, **self.extra_headers)
+        
+    def testRemoteUserIsRespected(self):
+        c = Client()
+        extra_headers = {'REMOTE_USER': 'iamnotanuser'}
+        res = c.get('/', {}, **self.extra_headers)
+
+        u = User.objects.get(username='iamnotanuser')
+        # wow, the user was created! this works.
+
+    def tearDown(self):
+        # Restore settings to avoid breaking other tests.
+        settings.MIDDLEWARE_CLASSES = self.curr_middleware
+        settings.AUTHENTICATION_BACKENDS = self.curr_auth
+        
 """
 >>> from models import User, AnonymousUser
 >>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw')
@@ -23,4 +71,4 @@
 []
 >>> a.user_permissions.all()
 []
-"""
\ No newline at end of file
+"""
Index: docs/request_response.txt
===================================================================
--- docs/request_response.txt	(revision 6820)
+++ docs/request_response.txt	(working copy)
@@ -109,6 +109,7 @@
         * ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
         * ``REMOTE_ADDR`` -- The IP address of the client.
         * ``REMOTE_HOST`` -- The hostname of the client.
+        * ``REMOTE_USER`` -- The user authenticated by the web server, if any.
         * ``REQUEST_METHOD`` -- A string such as ``"GET"`` or ``"POST"``.
         * ``SERVER_NAME`` -- The hostname of the server.
         * ``SERVER_PORT`` -- The port of the server.
Index: docs/auth_remote_user.txt
===================================================================
--- docs/auth_remote_user.txt	(revision 0)
+++ docs/auth_remote_user.txt	(revision 0)
@@ -0,0 +1,70 @@
+======================================================
+Authenticating against REMOTE_USER from the Web Server
+======================================================
+
+Typically on intranet sites users are already authenticated (i.e. in a Windows
+domain) by the web server (i.e. using IIS Integrated Authentication).
+
+When the web server takes care of authentication it sets the ``REMOTE_USER`` HTTP
+header for use in the underlying application (i.e. Django). Then it's up to
+this application take care of the authorization.
+
+Django brings all you need to make use of the ``REMOTE_USER`` header bringing you
+one step furder to single sign-on on enterprise infrastucure!
+
+We assume that you have already configured your web server to authenticate
+users, maybe with mod_auth_sspi in Apache, Integrated Authentication in IIS
+and so on.
+
+Configuring Django
+==================
+
+First of all, you must add the ``RemoteUserAuthMiddleware`` just **after**
+(never before) ``AuthenticationMiddleware``.
+
+After this, you'll have to create you authentication backend that will take
+care of checking that ``REMOTE_USER`` is valid. But don't be scared,
+``RemoteUserAuthBackend`` is here to help you.
+
+``RemoteUserAuthBackend`` provides a "template" of what you need, you could
+create a backend that simply inherits it and you are done. It will simply
+assume that ``REMOTE_USER`` is always correct and create ``User``objects for
+it.
+
+If you want more control, in you inherited authentication backend you can
+override a few methods:
+
+   * ``parse_user``: Should cleanup ``REMOTE_USER`` (i.e. strip @realm from
+     it). It takes the ``username`` as argument, and must return the cleaned
+     ``username``.
+   * ``unkown_user``: Should create and return a ``User`` object, will be
+     called when a ``User`` object does not exist for ``REMOTE_USER``. Takes
+     ``username`` as it's only argument.
+   * ``configure_user``: Will be called after ``unkown_user`` so you can
+     configure the recently created ``User`` object (in case you did not want
+     to override ``unkown_user``. Takes the ``User`` instance as an argument.
+     Should also return the ``User`` instance that represents the User.
+
+
+Examples:
+
+    settings.py::
+
+        MIDDLEWARE_CLASSES = (
+            'django.contrib.auth.middleware.AuthenticationMiddleware',
+            'django.contrib.auth.middleware.RemoteUserAuthMiddleware',
+            ...
+            )
+            
+        AUTHENTICATION_BACKENDS = (
+            'myproject.backends.MyDerivedBackend',
+        )
+
+    myproject/backends.py::
+
+        from django.contrib.auth.backends import RemoteUserAuthBackend
+
+        class MyDerivedBackend(RemoteUserAuthBackend):
+            # We don't really do anything, we are fine with the default
+            # behaviour.
+            pass 
Index: docs/authentication.txt
===================================================================
--- docs/authentication.txt	(revision 6820)
+++ docs/authentication.txt	(working copy)
@@ -1019,6 +1019,13 @@
 database-based scheme, or you can use the default system in tandem with other
 systems.
 
+There's a very specific situation/scenario in which you want to handle
+authentication at the web server's level (i.e. standard HTTP AUTH) and want
+Django to honour this authentication. This is covered in a separate page: 
+`Authenticating against REMOTE_USER from the Web Server`_
+
+.. _Authenticating against REMOTE_USER from the Web Server: ../auth_remote_user/
+
 Specifying authentication backends
 ----------------------------------
 
