diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index 3d76a42..cca1b70 100644
--- a/django/contrib/auth/__init__.py
+++ b/django/contrib/auth/__init__.py
@@ -2,6 +2,7 @@ import datetime
 from warnings import warn
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.importlib import import_module
+from django.contrib.auth import signals 
 
 SESSION_KEY = '_auth_user_id'
 BACKEND_SESSION_KEY = '_auth_user_backend'
@@ -62,8 +63,8 @@ def login(request, user):
     if user is None:
         user = request.user
     # TODO: It would be nice to support different login methods, like signed cookies.
-    user.last_login = datetime.datetime.now()
-    user.save()
+    signals.user_logged_in.send(sender=user.__class__, request=request,
+                                user=user)
 
     if SESSION_KEY in request.session:
         if request.session[SESSION_KEY] != user.id:
@@ -83,6 +84,14 @@ def logout(request):
     Removes the authenticated user's ID from the request and flushes their
     session data.
     """
+    # Dispatch the signal before the user is logged out so the receivers have a
+    # chance to find out *who* logged out.
+    user = getattr(request, 'user', None)
+    if hasattr(user, 'is_authenticated') and not user.is_authenticated():
+        user = None
+    signals.user_logged_out.send(sender=user.__class__, request=request,
+                                 user=user)
+
     request.session.flush()
     if hasattr(request, 'user'):
         from django.contrib.auth.models import AnonymousUser
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index 16a8b99..e37c5b3 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -2,6 +2,8 @@ import datetime
 import urllib
 
 from django.contrib import auth
+# Import the signals module to register the signal listener.
+from django.contrib.auth import signals
 from django.core.exceptions import ImproperlyConfigured
 from django.db import models
 from django.db.models.manager import EmptyManager
diff --git a/django/contrib/auth/signals.py b/django/contrib/auth/signals.py
new file mode 100644
index 0000000..ae66b6d
--- /dev/null
+++ b/django/contrib/auth/signals.py
@@ -0,0 +1,18 @@
+import datetime
+import django.dispatch
+
+user_logged_in = django.dispatch.Signal(providing_args=['request', 'user'])
+user_logged_out = django.dispatch.Signal(providing_args=['request', 'user'])
+
+
+def update_last_login(sender, user, **kwargs):
+    """
+    A signal receiver which updates the last_login date for the user logging
+    in.
+
+    """
+    user.last_login = datetime.datetime.now()
+    user.save()
+
+
+user_logged_in.connect(update_last_login)
diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py
index 98061a1..9f8b49f 100644
--- a/django/contrib/auth/tests/__init__.py
+++ b/django/contrib/auth/tests/__init__.py
@@ -5,6 +5,7 @@ from django.contrib.auth.tests.forms import UserCreationFormTest, Authentication
 from django.contrib.auth.tests.remote_user \
         import RemoteUserTest, RemoteUserNoCreateTest, RemoteUserCustomTest
 from django.contrib.auth.tests.models import ProfileTestCase
+from django.contrib.auth.tests.signals import SignalTestCase
 from django.contrib.auth.tests.tokens import TokenGeneratorTest
 from django.contrib.auth.tests.views \
         import PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest
diff --git a/django/contrib/auth/tests/signals.py b/django/contrib/auth/tests/signals.py
new file mode 100644
index 0000000..3806021
--- /dev/null
+++ b/django/contrib/auth/tests/signals.py
@@ -0,0 +1,47 @@
+from django.test import TestCase
+from django.contrib.auth import signals
+
+
+class SignalTestCase(TestCase):
+    urls = 'django.contrib.auth.tests.urls'
+    fixtures = ['authtestdata.json']
+
+    def listener_login(self, user, **kwargs):
+        self.logged_in.append(user)
+
+    def listener_logout(self, user, **kwargs):
+        self.logged_out.append(user)
+
+    def setUp(self):
+        """Set up the listeners and reset the logged in/logged out counters"""
+        self.logged_in = []
+        self.logged_out = []
+        signals.user_logged_in.connect(self.listener_login)
+        signals.user_logged_out.connect(self.listener_logout)
+
+    def tearDown(self):
+        """Disconnect the listeners"""
+        signals.user_logged_in.disconnect(self.listener_login)
+        signals.user_logged_out.disconnect(self.listener_logout)
+
+    def test_login(self):
+        # Only a successful login will trigger the signal.
+        self.client.login(username='testclient', password='bad')
+        self.assertEqual(len(self.logged_in), 0)
+        # Like this:
+        self.client.login(username='testclient', password='password')
+        self.assertEqual(len(self.logged_in), 1)
+        self.assertEqual(self.logged_in[0].username, 'testclient')
+
+    def test_logout_anonymous(self):
+        # The log_out function will still trigger the signal for anonymous
+        # users.
+        self.client.get('/logout/next_page/')
+        self.assertEqual(len(self.logged_out), 1)
+        self.assertEqual(self.logged_out[0], None)
+
+    def test_logout(self):
+        self.client.login(username='testclient', password='password')
+        self.client.get('/logout/next_page/')
+        self.assertEqual(len(self.logged_out), 1)
+        self.assertEqual(self.logged_out[0].username, 'testclient')
diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt
index 4c1db33..36ad071 100644
--- a/docs/ref/signals.txt
+++ b/docs/ref/signals.txt
@@ -12,6 +12,9 @@ A list of all the signals that Django sends.
     The :doc:`comment framework </ref/contrib/comments/index>` sends a :doc:`set
     of comment-related signals </ref/contrib/comments/signals>`.
 
+    The :ref:`authentication framework <topics-auth>` sends :ref:`signals when
+    a user is logged in / out <topics-auth-signals>`.
+
 Model signals
 =============
 
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index e0856e8..d69fd91 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -664,6 +664,44 @@ How to log a user out
     immediately after logging out, do that *after* calling
     :func:`django.contrib.auth.logout()`.
 
+.. _topics-auth-signals:
+
+Login and logout signals
+------------------------
+
+The auth framework uses two :ref:`signals <topic-signals>` that can be used for
+notification when a user logs in or out. 
+
+**:data:`django.contrib.auth.signals.user_logged_in`**
+
+Sent when a user logs in successfully.
+
+Arguments sent with this signal:
+
+    ``sender``
+        As above: the class of the user that just logged in.
+
+    ``request``
+        The current :class:`~django.http.HttpRequest` instance.
+
+    ``user``
+        The user instance that just logged in.
+
+**:data:`django.contrib.auth.signals.user_logged_out`**   
+
+Sent when the logout method is called.
+
+    ``sender``
+        As above: the class of the user that just logged out or ``None``
+        if the user was not authenticated.
+
+    ``request``
+        The current :class:`~django.http.HttpRequest` instance.
+
+    ``user``
+        The user instance that just logged out or ``None`` if the
+        user was not authenticated.
+
 Limiting access to logged-in users
 ----------------------------------
 
