diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 825cfc4e72fb719b726d7c2d0b74ca9870084dd7..d72772f21187fce52c81cf1a5d3eb03ed83795ca 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -565,26 +565,6 @@ function comment_preview(CommentInterface $comment, FormStateInterface $form_sta
   $entity = $comment->getCommentedEntity();
 
   if (!$form_state->getErrors()) {
-    // Attach the user and time information.
-    $author_name = $comment->getAuthorName();
-    if (!empty($author_name)) {
-      $account = user_load_by_name($author_name);
-    }
-    elseif (\Drupal::currentUser()->isAuthenticated() && empty($comment->is_anonymous)) {
-      $account = \Drupal::currentUser();
-    }
-
-    if (!empty($account) && $account->isAuthenticated()) {
-      $comment->setOwner($account);
-      $comment->setAuthorName($account->getUsername());
-    }
-    elseif (empty($author_name)) {
-      $comment->setAuthorName(\Drupal::config('user.settings')->get('anonymous'));
-    }
-
-    $created_time = !is_null($comment->getCreatedTime()) ? $comment->getCreatedTime() : REQUEST_TIME;
-    $comment->setCreatedTime($created_time);
-    $comment->changed->value = REQUEST_TIME;
     $comment->in_preview = TRUE;
     $comment_build = comment_view($comment);
     $comment_build['#weight'] = -100;
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index c96202bd5d0820f8ef2bd0186380a1241081ed57..15d1ece46f3acec599cc7f4eed5c0e653d32e388 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -121,8 +121,11 @@ public function form(array $form, FormStateInterface $form_state) {
     }
 
     // Prepare default values for form elements.
+    $author = '';
     if ($is_admin) {
-      $author = $comment->getAuthorName();
+      if (!$comment->getOwnerId()) {
+        $author = $comment->getAuthorName();
+      }
       $status = $comment->getStatus();
       if (empty($comment_preview)) {
         $form['#title'] = $this->t('Edit comment %title', array(
@@ -131,12 +134,6 @@ public function form(array $form, FormStateInterface $form_state) {
       }
     }
     else {
-      if ($this->currentUser->isAuthenticated()) {
-        $author = $this->currentUser->getUsername();
-      }
-      else {
-        $author = ($comment->getAuthorName() ? $comment->getAuthorName() : '');
-      }
       $status = ($this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED);
     }
 
@@ -145,35 +142,46 @@ public function form(array $form, FormStateInterface $form_state) {
       $date = !empty($comment->date) ? $comment->date : DrupalDateTime::createFromTimestamp($comment->getCreatedTime());
     }
 
-    // Add the author name field depending on the current user.
+    // The uid field is only displayed when a user with the permission
+    // 'administer comments' is editing an existing comment from an
+    // authenticated user.
+    $owner = $comment->getOwner();
+    $form['author']['uid'] = [
+      '#type' => 'entity_autocomplete',
+      '#target_type' => 'user',
+      '#default_value' => $owner->isAnonymous() ? NULL : $owner,
+      // A comment can be made anonymous by leaving this field empty therefore
+      // there is no need to list them in the autocomplete.
+      '#selection_settings' => ['include_anonymous' => FALSE],
+      '#title' => $this->t('Authored by'),
+      '#description' => $this->t('Leave blank for %anonymous.', ['%anonymous' => $config->get('anonymous')]),
+      '#access' => $is_admin,
+    ];
+
+    // The name field is displayed when an anonymous user is adding a comment or
+    // when a user with the permission 'administer comments' is editing an
+    // existing comment from an anonymous user.
     $form['author']['name'] = array(
       '#type' => 'textfield',
-      '#title' => $this->t('Your name'),
+      '#title' => $is_admin ? $this->t('Name for @anonymous', ['@anonymous' => $config->get('anonymous')]) : $this->t('Your name'),
       '#default_value' => $author,
       '#required' => ($this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT),
       '#maxlength' => 60,
+      '#access' => $this->currentUser->isAnonymous() || $is_admin,
       '#size' => 30,
+      '#attributes'=> [
+        'data-drupal-default-value' => $config->get('anonymous'),
+      ],
     );
+
     if ($is_admin) {
-      $form['author']['name']['#type'] = 'entity_autocomplete';
-      $form['author']['name']['#target_type'] = 'user';
-      $form['author']['name']['#selection_settings'] = ['include_anonymous' => FALSE];
-      $form['author']['name']['#process_default_value'] = FALSE;
-      // The user name is validated and processed in static::buildEntity() and
-      // static::validate().
-      $form['author']['name']['#element_validate'] = array();
-      $form['author']['name']['#title'] = $this->t('Authored by');
-      $form['author']['name']['#description'] = $this->t('Leave blank for %anonymous.', array('%anonymous' => $config->get('anonymous')));
-    }
-    elseif ($this->currentUser->isAuthenticated()) {
-      $form['author']['name']['#type'] = 'item';
-      $form['author']['name']['#value'] = $form['author']['name']['#default_value'];
-      $form['author']['name']['#theme'] = 'username';
-      $form['author']['name']['#account'] = $this->currentUser;
-      $form['author']['name']['#cache']['contexts'][] = 'user';
-    }
-    elseif($this->currentUser->isAnonymous()) {
-      $form['author']['name']['#attributes']['data-drupal-default-value'] = $config->get('anonymous');
+      // When editing a comment only display the name textfield if the uid field
+      // is empty.
+      $form['author']['name']['#states'] = [
+        'visible' => [
+          ':input[name="uid"]' => array('empty' => TRUE),
+        ],
+      ];
     }
 
     // Add author email and homepage fields depending on the current user.
@@ -263,22 +271,27 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
     else {
       $comment->setCreatedTime(REQUEST_TIME);
     }
-    $author_name = $form_state->getValue('name');
-
-    if (!$this->currentUser->isAnonymous()) {
-      // Assign the owner based on the given user name - none means anonymous.
-      $accounts = $this->entityManager->getStorage('user')
-        ->loadByProperties(array('name' => $author_name));
-      $account = reset($accounts);
-      $uid = $account ? $account->id() : 0;
-      $comment->setOwnerId($uid);
+    // Empty author ID should revert to anonymous.
+    $author_id = $form_state->getValue('uid');
+    if ($comment->id() && $this->currentUser->hasPermission('administer comments')) {
+      // Admin can leave the author ID blank to revert to anonymous.
+      $author_id = $author_id ?: 0;
     }
-
-    // If the comment was posted by an anonymous user and no author name was
-    // required, use "Anonymous" by default.
-    if ($comment->getOwnerId() === 0 && (!isset($author_name) || $author_name === '')) {
-      $comment->setAuthorName($this->config('user.settings')->get('anonymous'));
+    if (!is_null($author_id)) {
+      if ($author_id === 0 && $form['author']['name']['#access']) {
+        // Use the author name value when the form has access to the element and
+        // the author ID is anonymous.
+        $comment->setAuthorName($form_state->getValue('name'));
+      }
+      else {
+        // Ensure the author name is not set.
+        $comment->setAuthorName(NULL);
+      }
+    }
+    else {
+      $author_id = $this->currentUser->id();
     }
+    $comment->setOwnerId($author_id);
 
     // Validate the comment's subject. If not specified, extract from comment
     // body.
diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
index adacf9d092f470406e2b1c58ed5664fc40a2ffab..5aa5f4f147873eb1bfba6a3211fc74059e7bf579 100644
--- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
+++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php
@@ -190,16 +190,6 @@ public function viewElements(FieldItemListInterface $items) {
               $this->getFieldSetting('comment_type'),
             ]],
           ];
-
-          // @todo Remove this in https://www.drupal.org/node/2543334. Until
-          //   then, \Drupal\Core\Render\Renderer::hasPoorCacheability() isn't
-          //   integrated with cache context bubbling, so this duplicates the
-          //   contexts added by \Drupal\comment\CommentForm::form().
-          $output['comment_form']['#cache']['contexts'][] = 'user.permissions';
-          $output['comment_form']['#cache']['contexts'][] = 'user.roles:authenticated';
-          if ($this->currentUser->isAuthenticated()) {
-            $output['comment_form']['#cache']['contexts'][] = 'user';
-          }
         }
       }
 
diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php
index fd813f73d5b1f64a4e196acfab39dedbcdd43b48..60e243bf03df06bf2f66ff2c961323095c3c34bb 100644
--- a/core/modules/comment/src/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php
@@ -101,6 +101,7 @@ function testAnonymous() {
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('comment/' . $anonymous_comment3->id() . '/edit');
     $this->assertRaw($author_name, "The anonymous user's name is correct when editing the comment.");
+    $this->assertFieldByName('uid', '', 'The author field is empty (i.e. anonymous) when editing the comment.');
     $this->assertRaw($author_mail, "The anonymous user's email address is correct when editing the comment.");
 
     // Unpublish comment.
diff --git a/core/modules/comment/src/Tests/CommentInterfaceTest.php b/core/modules/comment/src/Tests/CommentInterfaceTest.php
index 113681167fa78119684b0d8a146da6eaf0bb7d23..0dc5ea294c8ba7a4909fc270751e4cfefc059d99 100644
--- a/core/modules/comment/src/Tests/CommentInterfaceTest.php
+++ b/core/modules/comment/src/Tests/CommentInterfaceTest.php
@@ -83,7 +83,7 @@ public function testCommentInterface() {
     )));
 
     // Test changing the comment author to "Anonymous".
-    $comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('name' => ''));
+    $comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('uid' => ''));
     $this->assertTrue($comment->getAuthorName() == t('Anonymous') && $comment->getOwnerId() == 0, 'Comment author successfully changed to anonymous.');
 
     // Test changing the comment author to an unverified user.
@@ -95,7 +95,7 @@ public function testCommentInterface() {
 
     // Test changing the comment author to a verified user.
     $this->drupalGet('comment/' . $comment->id() . '/edit');
-    $comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('name' => $this->webUser->getUsername()));
+    $comment = $this->postComment(NULL, $comment->comment_body->value, $comment->getSubject(), array('uid' => $this->webUser->getUsername() . ' (' . $this->webUser->id() . ')'));
     $this->assertTrue($comment->getAuthorName() == $this->webUser->getUsername() && $comment->getOwnerId() == $this->webUser->id(), 'Comment author successfully changed to a registered user.');
 
     $this->drupalLogout();
diff --git a/core/modules/comment/src/Tests/CommentPreviewTest.php b/core/modules/comment/src/Tests/CommentPreviewTest.php
index 644f89b5727e9e915e79adb57b7bb75cf4ba0d3b..2a9b1973f4960b178c74a98f28b07148efd6dc68 100644
--- a/core/modules/comment/src/Tests/CommentPreviewTest.php
+++ b/core/modules/comment/src/Tests/CommentPreviewTest.php
@@ -140,7 +140,7 @@ function testCommentEditPreviewSave() {
     $date = new DrupalDateTime('2008-03-02 17:23');
     $edit['subject[0][value]'] = $this->randomMachineName(8);
     $edit['comment_body[0][value]'] = $this->randomMachineName(16);
-    $edit['name'] = $web_user->getUsername();
+    $edit['uid'] = $web_user->getUsername() . ' (' . $web_user->id() . ')';
     $edit['date[date]'] = $date->format('Y-m-d');
     $edit['date[time]'] = $date->format('H:i:s');
     $raw_date = $date->getTimestamp();
@@ -154,13 +154,13 @@ function testCommentEditPreviewSave() {
     $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".');
     $this->assertText($edit['subject[0][value]'], 'Subject displayed.');
     $this->assertText($edit['comment_body[0][value]'], 'Comment displayed.');
-    $this->assertText($edit['name'], 'Author displayed.');
+    $this->assertText($web_user->getUsername(), 'Author displayed.');
     $this->assertText($expected_text_date, 'Date displayed.');
 
     // Check that the subject, comment, author and date fields are displayed with the correct values.
     $this->assertFieldByName('subject[0][value]', $edit['subject[0][value]'], 'Subject field displayed.');
     $this->assertFieldByName('comment_body[0][value]', $edit['comment_body[0][value]'], 'Comment field displayed.');
-    $this->assertFieldByName('name', $edit['name'], 'Author field displayed.');
+    $this->assertFieldByName('uid', $edit['uid'], 'Author field displayed.');
     $this->assertFieldByName('date[date]', $edit['date[date]'], 'Date field displayed.');
     $this->assertFieldByName('date[time]', $edit['date[time]'], 'Time field displayed.');
 
@@ -172,7 +172,7 @@ function testCommentEditPreviewSave() {
     $this->drupalGet('comment/' . $comment->id() . '/edit');
     $this->assertFieldByName('subject[0][value]', $edit['subject[0][value]'], 'Subject field displayed.');
     $this->assertFieldByName('comment_body[0][value]', $edit['comment_body[0][value]'], 'Comment field displayed.');
-    $this->assertFieldByName('name', $edit['name'], 'Author field displayed.');
+    $this->assertFieldByName('uid', $edit['uid'], 'Author field displayed.');
     $this->assertFieldByName('date[date]', $expected_form_date, 'Date field displayed.');
     $this->assertFieldByName('date[time]', $expected_form_time, 'Time field displayed.');
 
@@ -180,7 +180,7 @@ function testCommentEditPreviewSave() {
     $displayed = array();
     $displayed['subject[0][value]'] = (string) current($this->xpath("//input[@id='edit-subject-0-value']/@value"));
     $displayed['comment_body[0][value]'] = (string) current($this->xpath("//textarea[@id='edit-comment-body-0-value']"));
-    $displayed['name'] = (string) current($this->xpath("//input[@id='edit-name']/@value"));
+    $displayed['uid'] = (string) current($this->xpath("//input[@id='edit-uid']/@value"));
     $displayed['date[date]'] = (string) current($this->xpath("//input[@id='edit-date-date']/@value"));
     $displayed['date[time]'] = (string) current($this->xpath("//input[@id='edit-date-time']/@value"));
     $this->drupalPostForm('comment/' . $comment->id() . '/edit', $displayed, t('Save'));
@@ -188,10 +188,11 @@ function testCommentEditPreviewSave() {
     // Check that the saved comment is still correct.
     $comment_storage = \Drupal::entityManager()->getStorage('comment');
     $comment_storage->resetCache(array($comment->id()));
+    /** @var \Drupal\comment\CommentInterface $comment_loaded */
     $comment_loaded = Comment::load($comment->id());
     $this->assertEqual($comment_loaded->getSubject(), $edit['subject[0][value]'], 'Subject loaded.');
     $this->assertEqual($comment_loaded->comment_body->value, $edit['comment_body[0][value]'], 'Comment body loaded.');
-    $this->assertEqual($comment_loaded->getAuthorName(), $edit['name'], 'Name loaded.');
+    $this->assertEqual($comment_loaded->getOwner()->id(), $web_user->id(), 'Name loaded.');
     $this->assertEqual($comment_loaded->getCreatedTime(), $raw_date, 'Date loaded.');
     $this->drupalLogout();
 
@@ -200,6 +201,8 @@ function testCommentEditPreviewSave() {
     $user_edit = array();
     $expected_created_time = $comment_loaded->getCreatedTime();
     $this->drupalLogin($web_user);
+    // Web user cannot change the comment author.
+    unset($edit['uid']);
     $this->drupalPostForm('comment/' . $comment->id() . '/edit', $user_edit, t('Save'));
     $comment_storage->resetCache(array($comment->id()));
     $comment_loaded = Comment::load($comment->id());
diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php
index 12ea894ecdcb871aeb3dfecd1af21e9e52938b66..b487fd525066e4489396f049cc22ff8955d4ee63 100644
--- a/core/modules/comment/src/Tests/CommentTestBase.php
+++ b/core/modules/comment/src/Tests/CommentTestBase.php
@@ -70,6 +70,9 @@ protected function setUp() {
       'skip comment approval',
       'post comments',
       'access comments',
+      // Usernames aren't shown in comment edit form autocomplete unless this
+      // permission is granted.
+      'access user profiles',
       'access content',
      ));
     $this->webUser = $this->drupalCreateUser(array(
diff --git a/core/modules/comment/src/Tests/CommentTranslationUITest.php b/core/modules/comment/src/Tests/CommentTranslationUITest.php
index 6397c69a4d9f7bc2f8a98b9e6483b792625294cc..88c1d2fc1f01e5e5eb68d266cfa02ecf8e0202e8 100644
--- a/core/modules/comment/src/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/src/Tests/CommentTranslationUITest.php
@@ -41,7 +41,8 @@ class CommentTranslationUITest extends ContentTranslationUITestBase {
     'timezone',
     'url.query_args:_wrapper_format',
     'url.query_args.pagers:0',
-    'user'
+    'user.permissions',
+    'user.roles',
   ];
 
   /**
@@ -162,7 +163,7 @@ protected function doTestAuthoringInfo() {
         'created' => REQUEST_TIME - mt_rand(0, 1000),
       );
       $edit = array(
-        'name' => $user->getUsername(),
+        'uid' => $user->getUsername() . '(' . $user->id() . ')',
         'date[date]' => format_date($values[$langcode]['created'], 'custom', 'Y-m-d'),
         'date[time]' => format_date($values[$langcode]['created'], 'custom', 'H:i:s'),
       );