diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 99fc72e..98e90a6 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -161,7 +161,7 @@ TEMPLATE_LOADERS = (
 # Each one should be a callable that takes the request object as its
 # only parameter and returns a dictionary to add to the context.
 TEMPLATE_CONTEXT_PROCESSORS = (
-    'django.core.context_processors.auth',
+    'django.contrib.auth.context_processors.auth',
     'django.core.context_processors.debug',
     'django.core.context_processors.i18n',
     'django.core.context_processors.media',
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index 5f397ec..31a65e2 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -151,11 +151,16 @@ class AdminSite(object):
         from django.contrib.contenttypes.models import ContentType
 
         if not LogEntry._meta.installed:
-            raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.")
+            raise ImproperlyConfigured("Put 'django.contrib.admin' in your "
+                "INSTALLED_APPS setting in order to use the admin application.")
         if not ContentType._meta.installed:
-            raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.")
-        if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS:
-            raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.")
+            raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in "
+                "your INSTALLED_APPS setting in order to use the admin application.")
+        if not (
+            'django.contrib.auth.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS or
+            'django.core.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS):
+            raise ImproperlyConfigured("Put 'django.contrib.auth.context_processors.auth' "
+                "in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.")
 
     def admin_view(self, view, cacheable=False):
         """
diff --git a/django/contrib/auth/context_processors.py b/django/contrib/auth/context_processors.py
new file mode 100644
index 0000000..e63e0c5
--- /dev/null
+++ b/django/contrib/auth/context_processors.py
@@ -0,0 +1,34 @@
+from django.core.context_processors import PermWrapper
+from django.utils.functional import lazy, memoize, SimpleLazyObject
+
+def auth(request):
+    """
+    Returns context variables required by apps that use Django's authentication
+    system.
+
+    If there is no 'user' attribute in the request, uses AnonymousUser (from
+    django.contrib.auth).
+    """
+    # If we access request.user, request.session is accessed, which results in
+    # 'Vary: Cookie' being sent in every request that uses this context
+    # processor, which can easily be every request on a site if
+    # TEMPLATE_CONTEXT_PROCESSORS has this context processor added.  This kills
+    # the ability to cache.  So, we carefully ensure these attributes are lazy.
+    # We don't use django.utils.functional.lazy() for User, because that
+    # requires knowing the class of the object we want to proxy, which could
+    # break with custom auth backends.  LazyObject is a less complete but more
+    # flexible solution that is a good enough wrapper for 'User'.
+    def get_user():
+        if hasattr(request, 'user'):
+            return request.user
+        else:
+            from django.contrib.auth.models import AnonymousUser
+            return AnonymousUser()
+
+    return {
+        'user': SimpleLazyObject(get_user),
+        'messages': lazy(memoize(lambda: get_user().get_and_delete_messages(), {}, 0), list)(),
+        'perms':  lazy(lambda: PermWrapper(get_user()), PermWrapper)(),
+    }
+
+
diff --git a/django/core/context_processors.py b/django/core/context_processors.py
index 0dbd844..8faf5ac 100644
--- a/django/core/context_processors.py
+++ b/django/core/context_processors.py
@@ -8,37 +8,24 @@ RequestContext.
 """
 
 from django.conf import settings
-from django.utils.functional import lazy, memoize, SimpleLazyObject
 
 def auth(request):
     """
-    Returns context variables required by apps that use Django's authentication
-    system.
+    DEPRECATED. This context processor is the old location, and has been moved
+    to `django.contrib.auth.context_processors`.
 
-    If there is no 'user' attribute in the request, uses AnonymousUser (from
-    django.contrib.auth).
+    This function still exists for backwards-compatibility; it will be removed
+    in Django 1.4.
     """
-    # If we access request.user, request.session is accessed, which results in
-    # 'Vary: Cookie' being sent in every request that uses this context
-    # processor, which can easily be every request on a site if
-    # TEMPLATE_CONTEXT_PROCESSORS has this context processor added.  This kills
-    # the ability to cache.  So, we carefully ensure these attributes are lazy.
-    # We don't use django.utils.functional.lazy() for User, because that
-    # requires knowing the class of the object we want to proxy, which could
-    # break with custom auth backends.  LazyObject is a less complete but more
-    # flexible solution that is a good enough wrapper for 'User'.
-    def get_user():
-        if hasattr(request, 'user'):
-            return request.user
-        else:
-            from django.contrib.auth.models import AnonymousUser
-            return AnonymousUser()
-
-    return {
-        'user': SimpleLazyObject(get_user),
-        'messages': lazy(memoize(lambda: get_user().get_and_delete_messages(), {}, 0), list)(),
-        'perms':  lazy(lambda: PermWrapper(get_user()), PermWrapper)(),
-    }
+    import warnings
+    warnings.warn(
+        "The context processor at `django.core.context_processors.auth` is " \
+        "deprecated; use the path `django.contrib.auth.context_processors.auth` " \
+        "instead.",
+        PendingDeprecationWarning
+    )
+    from django.contrib.auth.context_processors import auth as auth_context_processor
+    return auth_context_processor(request)
 
 def debug(request):
     "Returns context variables helpful for debugging."
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 7e7f4c6..c77bec8 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -13,6 +13,12 @@ their deprecation, as per the :ref:`Django deprecation policy
           hooking up admin URLs.  This has been deprecated since the 1.1
           release.
 
+    * 1.4
+        * ``django.core.context_processors.auth``.  This release will
+          remove the old method in favor of the new method in
+          ``django.contrib.auth.context_processors.auth``.  This has been
+          deprecated since the 1.2 release.
+
     * 2.0
         * ``django.views.defaults.shortcut()``. This function has been moved
           to ``django.contrib.contenttypes.views.shortcut()`` as part of the
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index e8c673d..7043ef0 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -987,7 +987,7 @@ TEMPLATE_CONTEXT_PROCESSORS
 
 Default::
 
-    ("django.core.context_processors.auth",
+    ("django.contrib.auth.context_processors.auth",
     "django.core.context_processors.debug",
     "django.core.context_processors.i18n",
     "django.core.context_processors.media")
diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
index e3260a9..e92c3b4 100644
--- a/docs/ref/templates/api.txt
+++ b/docs/ref/templates/api.txt
@@ -308,7 +308,7 @@ called **context processors** -- that take a request object as their argument
 and return a dictionary of items to be merged into the context. By default,
 :setting:`TEMPLATE_CONTEXT_PROCESSORS` is set to::
 
-    ("django.core.context_processors.auth",
+    ("django.contrib.auth.context_processors.auth",
     "django.core.context_processors.debug",
     "django.core.context_processors.i18n",
     "django.core.context_processors.media")
@@ -348,8 +348,8 @@ optional, third positional argument, ``processors``. In this example, the
 
 Here's what each of the default processors does:
 
-django.core.context_processors.auth
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+django.contrib.auth.context_processors.auth
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every
 ``RequestContext`` will contain these three variables:
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index 152246d..44ca2e3 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -1218,8 +1218,8 @@ The currently logged-in user and his/her permissions are made available in the
    Technically, these variables are only made available in the template context
    if you use :class:`~django.template.context.RequestContext` *and* your
    :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
-   ``"django.core.context_processors.auth"``, which is default. For more, see
-   the :ref:`RequestContext docs <subclassing-context-requestcontext>`.
+   ``"django.contrib.auth.context_processors.auth"``, which is default. For
+   more, see the :ref:`RequestContext docs <subclassing-context-requestcontext>`.
 
 Users
 -----
diff --git a/tests/regressiontests/context_processors/tests.py b/tests/regressiontests/context_processors/tests.py
index 004f90e..0d19bef 100644
--- a/tests/regressiontests/context_processors/tests.py
+++ b/tests/regressiontests/context_processors/tests.py
@@ -41,7 +41,7 @@ class RequestContextProcessorTests(TestCase):
 
 class AuthContextProcessorTests(TestCase):
     """
-    Tests for the ``django.core.context_processors.auth`` processor
+    Tests for the ``django.contrib.auth.context_processors.auth`` processor
     """
     urls = 'regressiontests.context_processors.urls'
     fixtures = ['context-processors-users.xml']
