diff --git a/core/modules/user/src/Authentication/Provider/Cookie.php b/core/modules/user/src/Authentication/Provider/Cookie.php
index bac9e15..fee0d3a 100644
--- a/core/modules/user/src/Authentication/Provider/Cookie.php
+++ b/core/modules/user/src/Authentication/Provider/Cookie.php
@@ -8,7 +8,7 @@
 namespace Drupal\user\Authentication\Provider;
 
 use Drupal\Core\Authentication\AuthenticationProviderInterface;
-use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Session\UserSession;
 use Drupal\Core\Session\SessionConfigurationInterface;
@@ -28,23 +28,23 @@ class Cookie implements AuthenticationProviderInterface {
   protected $sessionConfiguration;
 
   /**
-   * The database connection.
+   * The entity manager.
    *
-   * @var \Drupal\Core\Database\Connection
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $connection;
+  protected $entityManager;
 
   /**
    * Constructs a new cookie authentication provider.
    *
    * @param \Drupal\Core\Session\SessionConfigurationInterface $session_configuration
    *   The session configuration.
-   * @param \Drupal\Core\Database\Connection $connection
-   *   The database connection.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
    */
-  public function __construct(SessionConfigurationInterface $session_configuration, Connection $connection) {
+  public function __construct(SessionConfigurationInterface $session_configuration, EntityManagerInterface $entity_manager) {
     $this->sessionConfiguration = $session_configuration;
-    $this->connection = $connection;
+    $this->entityManager = $entity_manager;
   }
 
   /**
@@ -73,27 +73,7 @@ public function authenticate(Request $request) {
    */
   protected function getUserFromSession(SessionInterface $session) {
     if ($uid = $session->get('uid')) {
-      // @todo Load the User entity in SessionHandler so we don't need queries.
-      // @see https://www.drupal.org/node/2345611
-      $values = $this->connection
-        ->query('SELECT * FROM {users_field_data} u WHERE u.uid = :uid AND u.default_langcode = 1', [':uid' => $uid])
-        ->fetchAssoc();
-
-      // Check if the user data was found and the user is active.
-      if (!empty($values) && $values['status'] == 1) {
-        // UserSession::getLastAccessedTime() returns session save timestamp,
-        // while User::getLastAccessedTime() returns the user 'access'
-        // timestamp. This ensures they are synchronized.
-        $values['timestamp'] = $values['access'];
-
-        // Add the user's roles.
-        $rids = $this->connection
-          ->query('SELECT roles_target_id FROM {user__roles} WHERE entity_id = :uid', [':uid' => $values['uid']])
-          ->fetchCol();
-        $values['roles'] = array_merge([AccountInterface::AUTHENTICATED_ROLE], $rids);
-
-        return new UserSession($values);
-      }
+      return $this->entityManager->getStorage('user')->load($uid);
     }
 
     // This is an anonymous session.
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 1a78c98..cf05b7c 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -161,9 +161,22 @@ public function getRoles($exclude_locked_roles = FALSE) {
       }
     }
 
-    foreach ($this->get('roles') as $role) {
-      if ($role->target_id) {
-        $roles[] = $role->target_id;
+    // Optimize for the case where the field object has not been initialized
+    // yet, directly access the values.
+    if (!isset($this->fields['roles'])) {
+      if (isset($this->values['roles'][LanguageInterface::LANGCODE_DEFAULT][0])) {
+        foreach ($this->values['roles'][LanguageInterface::LANGCODE_DEFAULT] as $values) {
+          if (isset($values['target_id'])) {
+            $roles[] = $values['target_id'];
+          }
+        }
+      }
+    }
+    else {
+      foreach ($this->get('roles') as $role) {
+        if ($role->target_id) {
+          $roles[] = $role->target_id;
+        }
       }
     }
 
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 0a55b6e..57325a6 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -17,7 +17,7 @@ services:
       - { name: access_check, applies_to: _user_is_logged_in }
   authentication.cookie:
     class: Drupal\user\Authentication\Provider\Cookie
-    arguments: ['@session_configuration', '@database']
+    arguments: ['@session_configuration', '@entity.manager']
     tags:
       - { name: authentication_provider, priority: 0 }
   user.data:
