diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
index ce78a40..5cdbfd7 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
@@ -62,4 +62,23 @@ public static function schema(FieldDefinitionInterface $field_definition) {
     );
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConstraints() {
+    $constraints = parent::getConstraints();
+
+    // Not all plugins that inherit from this class have a configurable maximum
+    // length, so we only apply the length constraint conditionally. Example:
+    // UuidItem has a fixed length of 128.
+    if ($max_length = $this->getFieldSetting('max_length')) {
+      $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
+      $constraints[] = $constraint_manager->create('ComplexData', array(
+        'value' => array('Length' => array('max' => $max_length))
+      ));
+    }
+
+    return $constraints;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
index 4cad163..e451b01 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UriItem.php
@@ -8,7 +8,6 @@
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
 use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\TypedData\DataDefinition;
 
 /**
@@ -21,7 +20,7 @@
  *   configurable = FALSE
  * )
  */
-class UriItem extends FieldItemBase {
+class UriItem extends StringItem {
 
   /**
    * Field definitions of the contained properties.
diff --git a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
index 3c8b696..8aef5c6 100644
--- a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
+++ b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
@@ -383,7 +383,8 @@ public static function baseFieldDefinitions($entity_type) {
 
     $fields['subject'] = FieldDefinition::create('string')
       ->setLabel(t('Subject'))
-      ->setDescription(t('The comment title or subject.'));
+      ->setDescription(t('The comment title or subject.'))
+      ->setSetting('max_length', 64);
 
     $fields['uid'] = FieldDefinition::create('entity_reference')
       ->setLabel(t('User ID'))
@@ -396,19 +397,27 @@ public static function baseFieldDefinitions($entity_type) {
     $fields['name'] = FieldDefinition::create('string')
       ->setLabel(t('Name'))
       ->setDescription(t("The comment author's name."))
-      ->setSetting('default_value', '');
+      ->setSettings(array(
+        'default_value' => '',
+        'max_length' => 60,
+      ))
+      ->setConstraints(array('CommentName' => array()));
 
     $fields['mail'] = FieldDefinition::create('email')
       ->setLabel(t('Email'))
       ->setDescription(t("The comment author's e-mail address."));
 
-    $fields['homepage'] = FieldDefinition::create('string')
+    $fields['homepage'] = FieldDefinition::create('uri')
       ->setLabel(t('Homepage'))
-      ->setDescription(t("The comment author's home page address."));
+      ->setDescription(t("The comment author's home page address."))
+      // URIs are not length limited by RFC 2616, but we can only store 255
+      // characters in our comment DB schema.
+      ->setSetting('max_length', 255);
 
     $fields['hostname'] = FieldDefinition::create('string')
       ->setLabel(t('Hostname'))
-      ->setDescription(t("The comment author's hostname."));
+      ->setDescription(t("The comment author's hostname."))
+      ->setSetting('max_length', 128);
 
     // @todo Convert to a "created" field in https://drupal.org/node/2145103.
     $fields['created'] = FieldDefinition::create('integer')
@@ -427,7 +436,8 @@ public static function baseFieldDefinitions($entity_type) {
 
     $fields['thread'] = FieldDefinition::create('string')
       ->setLabel(t('Thread place'))
-      ->setDescription(t("The alphadecimal representation of the comment's place in a thread, consisting of a base 36 string prefixed by an integer indicating its length."));
+      ->setDescription(t("The alphadecimal representation of the comment's place in a thread, consisting of a base 36 string prefixed by an integer indicating its length."))
+      ->setSetting('max_length', 255);
 
     $fields['entity_type'] = FieldDefinition::create('string')
       ->setLabel(t('Entity type'))
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraint.php b/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraint.php
new file mode 100644
index 0000000..221486a
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraint.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\Validation\Constraint\CommentNameConstraint.
+ */
+
+namespace Drupal\comment\Plugin\Validation\Constraint;
+
+use Drupal\Component\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Supports validating comment author names.
+ *
+ * @Plugin(
+ *   id = "CommentName",
+ *   label = @Translation("Comment author name", context = "Validation")
+ * )
+ */
+class CommentNameConstraint extends Constraint {
+
+  public $message = 'The name %name you used belongs to a registered user.';
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraintValidator.php b/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraintValidator.php
new file mode 100644
index 0000000..fe3ae54
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/Validation/Constraint/CommentNameConstraintValidator.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Plugin\Validation\Constraint\CommentNameConstraintValidator.
+ */
+
+namespace Drupal\comment\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Validates the CommentName constraint.
+ */
+class CommentNameConstraintValidator extends ConstraintValidator {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($field_item, Constraint $constraint) {
+    $author_name = $field_item->value;
+    if (isset($author_name) && ($author_name !== '')) {
+      // @todo Improve DX of this after https://drupal.org/node/2078387.
+      $author_is_unauthenticated = ($field_item->getEntity()->uid->value === 0);
+
+      // Do not allow unauthenticated comment authors to use a name that is
+      // taken by a registered user.
+      if ($author_is_unauthenticated) {
+        $users = \Drupal::entityManager()->getStorageController('user')->loadByProperties(array('name' => $author_name));
+        if (!empty($users)) {
+          $this->context->addViolation($constraint->message, array('%name' => $author_name));
+        }
+      }
+    }
+  }
+}
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php
new file mode 100644
index 0000000..b204eb2
--- /dev/null
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\comment\Tests\CommentValidationTest.
+ */
+
+namespace Drupal\comment\Tests;
+
+use Drupal\system\Tests\Entity\EntityUnitTestBase;
+
+/**
+ * Tests comment validation constraints.
+ */
+class CommentValidationTest extends EntityUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('comment', 'node');
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment Validation',
+      'description' => 'Tests the comment validation constraints.',
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_revision'));
+  }
+
+  /**
+   * Tests the comment validation constraints.
+   */
+  public function testValidation() {
+    $node = $this->entityManager->getStorageController('node')->create(array(
+      'type' => 'page',
+      'title' => 'test',
+    ));
+    $node->save();
+
+    $comment = $this->entityManager->getStorageController('comment')->create(array(
+      'entity_id' => $node->id(),
+      // Just use some non-existing dummy field ID here, we are not testing
+      // that.
+      'field_id' => 'test',
+    ));
+    $violations = $comment->validate();
+    $this->assertEqual(count($violations), 0, 'No violations when validating a default comment.');
+
+    $comment->set('subject', $this->randomString(65));
+    $this->assertLengthViolation($comment, 'subject', 64);
+    // Make the subject valid.
+    $comment->set('subject', $this->randomString());
+
+    $comment->set('name', $this->randomString(61));
+    $this->assertLengthViolation($comment, 'name', 60);
+    // Validate a name collision between an anonymous comment author name and an
+    // existing user account name.
+    $user = entity_create('user', array('name' => 'test'));
+    $user->save();
+    $comment->set('name', 'test');
+    $violations = $comment->validate();
+    $this->assertEqual(count($violations), 1, "Violation found on author name collision");
+    $this->assertEqual($violations[0]->getPropertyPath(), "name");
+    $this->assertEqual($violations[0]->getMessage(), t('The name %name you used belongs to a registered user.', array('%name' => 'test')));
+
+    // Make the name valid.
+    $comment->set('name', $this->randomString());
+
+    $comment->set('mail', 'invalid');
+    $violations = $comment->validate();
+    $this->assertEqual(count($violations), 1, 'Violation found when email is invalid');
+    $this->assertEqual($violations[0]->getPropertyPath(), 'mail.0.value');
+    $this->assertEqual($violations[0]->getMessage(), t('This value is not a valid email address.'));
+    $comment->set('mail', NULL);
+
+    $comment->set('homepage', 'http://example.com/' . $this->randomName(237));
+    $this->assertLengthViolation($comment, 'homepage', 255);
+
+    $comment->set('homepage', 'invalid');
+    $violations = $comment->validate();
+    $this->assertEqual(count($violations), 1, 'Violation found when homepage is invalid');
+    $this->assertEqual($violations[0]->getPropertyPath(), 'homepage.0.value');
+    // @todo This message should be improved in https://drupal.org/node/2171539
+    $this->assertEqual($violations[0]->getMessage(), t('This value should be of the correct primitive type.'));
+    $comment->set('homepage', NULL);
+
+    $comment->set('hostname', $this->randomString(129));
+    $this->assertLengthViolation($comment, 'hostname', 128);
+    $comment->set('hostname', NULL);
+
+    $comment->set('thread', $this->randomString(256));
+    $this->assertLengthViolation($comment, 'thread', 255);
+  }
+
+  /**
+   * Verifies that a length violation exists for the given field.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface\CommentInterface $comment
+   *   The comment object to validate.
+   * @param string $field_name
+   *   The field that violates the maximum length.
+   * @param int $length
+   *   Number of characters that was exceeded.
+   */
+  protected function assertLengthViolation($comment, $field_name, $length) {
+    $violations = $comment->validate();
+    $this->assertEqual(count($violations), 1, "Violation found when $field_name is too long.");
+    $this->assertEqual($violations[0]->getPropertyPath(), "$field_name.0.value");
+    $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => $length)));
+  }
+}
