diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index ec3af63..8d95de6 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -94,6 +94,10 @@ class Permission(models.Model):
         return (self.codename,) + self.content_type.natural_key()
     natural_key.dependencies = ['contenttypes.contenttype']
 
+class GroupManager(models.Manager):
+    def get_by_natural_key(self, name):
+        return self.get(name=name)
+
 class Group(models.Model):
     """Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
 
@@ -103,6 +107,7 @@ class Group(models.Model):
     """
     name = models.CharField(_('name'), max_length=80, unique=True)
     permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True)
+    objects = GroupManager()
 
     class Meta:
         verbose_name = _('group')
@@ -111,6 +116,9 @@ class Group(models.Model):
     def __unicode__(self):
         return self.name
 
+    def natural_key(self):
+        return (self.name,)
+
 class UserManager(models.Manager):
     def create_user(self, username, email, password=None):
         """
@@ -150,6 +158,9 @@ class UserManager(models.Manager):
         from random import choice
         return ''.join([choice(allowed_chars) for i in range(length)])
 
+    def get_by_natural_key(self, username):
+        return self.get(username=username)
+
 
 # A few helper functions for common logic between User and AnonymousUser.
 def _user_get_all_permissions(user, obj):
@@ -393,6 +404,9 @@ class User(models.Model):
         return self._message_set
     message_set = property(_get_message_set)
 
+    def natural_key(self):
+        return (self.username,)
+
 class Message(models.Model):
     """
     The message system is a lightweight way to queue messages for given
diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py
index 3a8f55b..9dda8e2 100644
--- a/django/contrib/auth/tests/__init__.py
+++ b/django/contrib/auth/tests/__init__.py
@@ -8,7 +8,7 @@ from django.contrib.auth.tests.forms import (UserCreationFormTest,
     UserChangeFormTest, PasswordResetFormTest)
 from django.contrib.auth.tests.remote_user import (RemoteUserTest,
     RemoteUserNoCreateTest, RemoteUserCustomTest)
-from django.contrib.auth.tests.models import ProfileTestCase
+from django.contrib.auth.tests.models import ProfileTestCase, NaturalKeysTestCase
 from django.contrib.auth.tests.signals import SignalTestCase
 from django.contrib.auth.tests.tokens import TokenGeneratorTest
 from django.contrib.auth.tests.views import (PasswordResetTest,
diff --git a/django/contrib/auth/tests/models.py b/django/contrib/auth/tests/models.py
index 754c6db..925ed7d 100644
--- a/django/contrib/auth/tests/models.py
+++ b/django/contrib/auth/tests/models.py
@@ -1,6 +1,6 @@
 from django.conf import settings
 from django.test import TestCase
-from django.contrib.auth.models import User, SiteProfileNotAvailable
+from django.contrib.auth.models import Group, User, SiteProfileNotAvailable
 
 class ProfileTestCase(TestCase):
     fixtures = ['authtestdata.json']
@@ -33,3 +33,15 @@ class ProfileTestCase(TestCase):
         # module that doesn't exist
         settings.AUTH_PROFILE_MODULE = 'foo.bar'
         self.assertRaises(SiteProfileNotAvailable, user.get_profile)
+
+
+class NaturalKeysTestCase(TestCase):
+    fixtures = ['authtestdata.json']
+    def test_user_natural_key(self):
+        staff_user = User.objects.get(username='staff')
+        self.assertEquals(User.objects.get_by_natural_key('staff'), staff_user)
+        self.assertEquals(staff_user.natural_key(), ('staff',))
+
+    def test_group_natural_key(self):
+        users_group = Group.objects.create(name='users')
+        self.assertEquals(Group.objects.get_by_natural_key('users'), users_group)
diff --git a/docs/topics/serialization.txt b/docs/topics/serialization.txt
index c8acc85..f506f20 100644
--- a/docs/topics/serialization.txt
+++ b/docs/topics/serialization.txt
@@ -400,3 +400,9 @@ dependency, we add one extra line::
 This definition ensures that ``ContentType`` models are serialized before
 ``Permission`` models. In turn, any object referencing ``Permission`` will
 be serialized after both ``ContentType`` and ``Permission``.
+
+.. note::
+
+    Besides the ``Permission`` model, both ``User`` and ``Group`` models
+    in ``contrib.auth`` support natural keys.
+
