diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 825cfc4..dae5696 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -568,7 +568,7 @@ function comment_preview(CommentInterface $comment, FormStateInterface $form_sta
     // Attach the user and time information.
     $author_name = $comment->getAuthorName();
     if (!empty($author_name)) {
-      $account = user_load_by_name($author_name);
+      $account = $comment->getOwner();
     }
     elseif (\Drupal::currentUser()->isAuthenticated() && empty($comment->is_anonymous)) {
       $account = \Drupal::currentUser();
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index c96202b..93459e1 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -152,29 +152,23 @@ public function form(array $form, FormStateInterface $form_state) {
       '#default_value' => $author,
       '#required' => ($this->currentUser->isAnonymous() && $anonymous_contact == COMMENT_ANONYMOUS_MUST_CONTACT),
       '#maxlength' => 60,
+      '#access' => $this->currentUser->isAnonymous() || (!$comment->getOwnerId() && $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');
-    }
+
+    $owner = $comment->getOwner();
+    $form['author']['admin_select'] = [
+      '#type' => 'entity_autocomplete',
+      '#target_type' => 'user',
+      '#default_value' => $owner->isAnonymous() ? NULL : $owner,
+      '#selection_settings' => ['include_anonymous' => TRUE],
+      '#title' => $this->t('Authored by'),
+      '#description' => $this->t('Leave blank for %anonymous.', array('%anonymous' => $config->get('anonymous'))),
+      '#access' => $is_admin,
+    ];
 
     // Add author email and homepage fields depending on the current user.
     $form['author']['mail'] = array(
@@ -263,16 +257,27 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
     else {
       $comment->setCreatedTime(REQUEST_TIME);
     }
+    // Empty author-ID should revert to anonymous.
+    $author_id = $form_state->getValue('admin_select');
     $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);
+    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 (!is_null($author_id)) {
+      $account = $this->entityManager->getStorage('user')->load($author_id);
+      if ($author_id || !$form['author']['name']['#access']) {
+        $comment->setAuthorName($account->getUserName());
+      }
+      else {
+        // Anonymous user - use the author name value.
+        $comment->setAuthorName($author_name);
+      }
+    }
+    else {
+      $author_id = $this->currentUser->id();
     }
+    $comment->setOwnerId($author_id);
 
     // If the comment was posted by an anonymous user and no author name was
     // required, use "Anonymous" by default.
diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php
index fd813f7..96d01d8 100644
--- a/core/modules/comment/src/Tests/CommentAnonymousTest.php
+++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php
@@ -100,7 +100,7 @@ function testAnonymous() {
     // Make sure the user data appears correctly when editing the comment.
     $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('admin_select', '', "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 1136811..2795628 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('admin_select' => ''));
     $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('admin_select' => $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 ae92de0..363e3bb 100644
--- a/core/modules/comment/src/Tests/CommentPreviewTest.php
+++ b/core/modules/comment/src/Tests/CommentPreviewTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\comment\Tests;
 
 use Drupal\comment\CommentManagerInterface;
+use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\comment\Entity\Comment;
@@ -50,13 +51,15 @@ function testCommentPreview() {
     $edit['subject[0][value]'] = $this->randomMachineName(8);
     $edit['comment_body[0][value]'] = $this->randomMachineName(16);
     $this->drupalPostForm('node/' . $this->node->id(), $edit, t('Preview'));
-    $this->assertEscaped('<em>' . $this->webUser->id() . '</em>');
+    $this->assertEscaped($this->webUser->getUsername());
 
     \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE);
     $this->drupalPostForm('node/' . $this->node->id(), $edit, t('Preview'));
     $this->assertTrue(SafeMarkup::isSafe($this->webUser->getUsername()), 'Username is marked safe');
-    $this->assertNoEscaped('<em>' . $this->webUser->id() . '</em>');
-    $this->assertRaw('<em>' . $this->webUser->id() . '</em>');
+    $this->assertRaw($this->webUser->getUsername());
+
+    // Disable altering of usernames.
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter', FALSE);
 
     // Add a user picture.
     $image = current($this->drupalGetTestFiles('image'));
@@ -140,7 +143,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['admin_select'] = $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 +157,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('admin_select', $edit['admin_select'], '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 +175,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('admin_select', $edit['admin_select'], '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 +183,6 @@ 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['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 +190,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 +203,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['admin_select']);
     $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 12ea894..351f6da 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',
+      // Username's 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 6397c69..efb6637 100644
--- a/core/modules/comment/src/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/src/Tests/CommentTranslationUITest.php
@@ -162,7 +162,7 @@ protected function doTestAuthoringInfo() {
         'created' => REQUEST_TIME - mt_rand(0, 1000),
       );
       $edit = array(
-        'name' => $user->getUsername(),
+        'admin_select' => $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'),
       );
diff --git a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module
index a036c65..cd6e23c 100644
--- a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module
+++ b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module
@@ -5,7 +5,7 @@
  * Support module for user hooks testing.
  */
 
-use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Render\SafeString;
 
 /**
  * Implements hook_user_format_name_alter().
@@ -13,7 +13,10 @@
 function user_hooks_test_user_format_name_alter(&$name, $account) {
   if (\Drupal::state()->get('user_hooks_test_user_format_name_alter', FALSE)) {
     if (\Drupal::state()->get('user_hooks_test_user_format_name_alter_safe', FALSE)) {
-      $name = SafeMarkup::format('<em>@uid</em>', array('@uid' => $account->id()));
+      // Make $name a SafeStringInterface object.
+      // @todo change this to SafeMarkup::format() after
+      //  https://www.drupal.org/node/2559971 lands.
+      $name = SafeString::create('<em>@id</em>', ['@id' => $account->id()]);
     }
     else {
       $name = '<em>' . $account->id() . '</em>';
