diff --git a/core/modules/user/src/Authentication/Provider/Cookie.php b/core/modules/user/src/Authentication/Provider/Cookie.php
index 22ac903..c8385b6 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;
   }
 
   /**
@@ -58,41 +58,14 @@ public function applies(Request $request) {
    * {@inheritdoc}
    */
   public function authenticate(Request $request) {
-    return $this->getUserFromSession($request->getSession());
-  }
-
-  /**
-   * Returns the UserSession object for the given session.
-   *
-   * @param \Symfony\Component\HttpFoundation\Session\SessionInterface $session
-   *   The session.
-   *
-   * @return \Drupal\Core\Session\AccountInterface|NULL
-   *   The UserSession object for the current user, or NULL if this is an
-   *   anonymous session.
-   */
-  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) {
-        // 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);
+    if ($uid = $request->getSession()->get('uid')) {
+      /** @var \Drupal\user\UserInterface $user */
+      if ($user = $this->entityManager->getStorage('user')->load($uid)) {
+        if ($user->isActive()) {
+          return $user;
+        }
       }
     }
-
-    // This is an anonymous session.
-    return NULL;
   }
 
 }
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index fa4db6f..ec98e90 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -48,7 +48,8 @@
  *   entity_keys = {
  *     "id" = "uid",
  *     "langcode" = "langcode",
- *     "uuid" = "uuid"
+ *     "uuid" = "uuid",
+ *     "status" = "status"
  *   },
  *   links = {
  *     "canonical" = "/user/{user}",
@@ -154,9 +155,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;
+        }
       }
     }
 
@@ -274,14 +288,14 @@ public function setLastLoginTime($timestamp) {
    * {@inheritdoc}
    */
   public function isActive() {
-    return $this->get('status')->value == 1;
+    return $this->getEntityKey('status') == 1;
   }
 
   /**
    * {@inheritdoc}
    */
   public function isBlocked() {
-    return $this->get('status')->value == 0;
+    return $this->getEntityKey('status') == 0;
   }
 
   /**
diff --git a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php
index 4f004a0..dae3c6c 100644
--- a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php
+++ b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Tests\user\Unit\Plugin\Core\Entity;
 
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Tests\Core\Session\UserSessionTest;
 use Drupal\user\Entity\User;
   use Drupal\user\RoleInterface;
@@ -21,24 +22,28 @@ class UserTest extends UserSessionTest {
    * {@inheritdoc}
    */
   protected function createUserSession(array $rids = array(), $authenticated = FALSE) {
+    $roles = array();
+    foreach ($rids as $rid) {
+      $roles[] = array(
+        'target_id' => $rid,
+      );
+    }
+    $values = ['roles' => [LanguageInterface::LANGCODE_DEFAULT => $roles]];
+
     $user = $this->getMockBuilder('Drupal\user\Entity\User')
       ->disableOriginalConstructor()
-      ->setMethods(array('get', 'id'))
+      ->setMethods(array('id'))
       ->getMock();
+
+    $reflect = new \ReflectionObject($user);
+    $property = $reflect->getProperty('values');
+    $property->setAccessible(TRUE);
+    $property->setValue($user, $values);
+
     $user->expects($this->any())
       ->method('id')
       // @todo Also test the uid = 1 handling.
       ->will($this->returnValue($authenticated ? 2 : 0));
-    $roles = array();
-    foreach ($rids as $rid) {
-      $roles[] = (object) array(
-        'target_id' => $rid,
-      );
-    }
-    $user->expects($this->any())
-      ->method('get')
-      ->with('roles')
-      ->will($this->returnValue($roles));
     return $user;
   }
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index d175edf..0c0657c 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -752,6 +752,7 @@ function _user_cancel($edit, $account, $method) {
   // regenerate it because batch API uses the session ID, we will regenerate it
   // in _user_cancel_session_regenerate().
   if ($account->id() == \Drupal::currentUser()->id()) {
+    \Drupal::request()->getSession()->remove('uid');
     \Drupal::currentUser()->setAccount(new AnonymousUserSession());
   }
 }
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index be4e679..0f81d58 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 }
   user.authentication.cookie:
     class: Drupal\user\Authentication\Provider\Cookie
-    arguments: ['@session_configuration', '@database']
+    arguments: ['@session_configuration', '@entity.manager']
     tags:
       - { name: authentication_provider, provider_id: 'cookie', priority: 0, global: TRUE }
   user.data:
