diff --git a/core/core.services.yml b/core/core.services.yml
index 32881da..acc0a19 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -738,11 +738,10 @@ services:
       - { name: event_subscriber }
     arguments: ['@authentication']
   current_user:
-    class: Drupal\Core\Session\AccountInterface
-    factory_method: authenticate
-    factory_service: authentication
-    arguments: ['@request']
-    synchronized: true
+    class: Drupal\Core\Authentication\AccountProxy
+    arguments: ['@authentication']
+    calls:
+      - [setRequest, ['@?request=']]
   asset.css.collection_renderer:
     class: Drupal\Core\Asset\CssCollectionRenderer
     arguments: [ '@state' ]
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index e38cfda..ffac351 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1493,10 +1493,10 @@ function drupal_handle_request($test_only = FALSE) {
  * Returns the time zone of the current user.
  */
 function drupal_get_user_timezone() {
-  global $user;
   $config = \Drupal::config('system.date');
+  $user = \Drupal::currentUser();
 
-  if ($user && $config->get('timezone.user.configurable') && $user->isAuthenticated() && $user->getTimezone()) {
+  if ($user->hasAccount() && $config->get('timezone.user.configurable') && $user->isAuthenticated() && $user->getTimezone()) {
     return $user->getTimezone();
   }
   else {
diff --git a/core/includes/session.inc b/core/includes/session.inc
index 839ead8..bfadc89 100644
--- a/core/includes/session.inc
+++ b/core/includes/session.inc
@@ -72,7 +72,7 @@ function _drupal_session_close() {
  *   The user's session, or an empty string if no session exists.
  */
 function _drupal_session_read($sid) {
-  global $user;
+  $user = \Drupal::currentUser();
 
   // Write and Close handlers are called after destructing objects
   // since PHP 5.0.5.
@@ -85,7 +85,7 @@ function _drupal_session_read($sid) {
   $insecure_session_name = substr(session_name(), 1);
   $cookies = \Drupal::request()->cookies;
   if (!$cookies->has(session_name()) && !$cookies->has($insecure_session_name)) {
-    $user = new UserSession();
+    $user->setAccount(new UserSession());
     return '';
   }
 
@@ -115,19 +115,19 @@ function _drupal_session_read($sid) {
     // Add roles element to $user.
     $rids = db_query("SELECT ur.rid FROM {users_roles} ur WHERE ur.uid = :uid", array(':uid' => $values['uid']))->fetchCol();
     $values['roles'] = array_merge(array(DRUPAL_AUTHENTICATED_RID), $rids);
-    $user = new UserSession($values);
+    $user->setAccount(new UserSession($values));
   }
   elseif ($values) {
     // The user is anonymous or blocked. Only preserve two fields from the
     // {sessions} table.
-    $user = new UserSession(array(
+    $user->setAccount(new UserSession(array(
       'session' => $values['session'],
       'access' => $values['access'],
-    ));
+    )));
   }
   else {
     // The session has expired.
-    $user = new UserSession();
+    $user->setAccount(new UserSession());
   }
 
   // Store the session that was read for comparison in _drupal_session_write().
@@ -159,7 +159,7 @@ function _drupal_session_read($sid) {
  *   Always returns TRUE.
  */
 function _drupal_session_write($sid, $value) {
-  global $user;
+  $user = \Drupal::currentUser();
 
   // The exception handler is not active at this point, so we need to do it
   // manually.
@@ -241,7 +241,7 @@ function _drupal_session_write($sid, $value) {
  * Initializes the session handler, starting a session if needed.
  */
 function drupal_session_initialize() {
-  global $user;
+  $user = \Drupal::currentUser();
 
   session_set_save_handler('_drupal_session_open', '_drupal_session_close', '_drupal_session_read', '_drupal_session_write', '_drupal_session_destroy', '_drupal_session_garbage_collection');
 
@@ -253,7 +253,7 @@ function drupal_session_initialize() {
     // anonymous users not use a session cookie unless something is stored in
     // $_SESSION. This allows HTTP proxies to cache anonymous pageviews.
     drupal_session_start();
-    if ($user->isAuthenticated() || !empty($_SESSION)) {
+    if (($user->hasAccount() && $user->isAuthenticated()) || !empty($_SESSION)) {
       drupal_page_is_cacheable(FALSE);
     }
   }
@@ -263,7 +263,7 @@ function drupal_session_initialize() {
     // processes (like drupal_get_token()) needs to know the future
     // session ID in advance.
     $GLOBALS['lazy_session'] = TRUE;
-    $user = drupal_anonymous_user();
+    $user->setAccount(drupal_anonymous_user());
     // Less random sessions (which are much faster to generate) are used for
     // anonymous users than are generated in drupal_session_regenerate() when
     // a user becomes authenticated.
@@ -304,14 +304,14 @@ function drupal_session_start() {
  * If an anonymous user already have an empty session, destroy it.
  */
 function drupal_session_commit() {
-  global $user;
+  $user = \Drupal::currentUser();
 
   if (!drupal_save_session()) {
     // We don't have anything to do if we are not allowed to save the session.
     return;
   }
 
-  if ($user->isAnonymous() && empty($_SESSION)) {
+  if ($user->hasAccount() && $user->isAnonymous() && empty($_SESSION)) {
     // There is no session data to store, destroy the session if it was
     // previously started.
     if (drupal_session_started()) {
@@ -353,7 +353,7 @@ function drupal_session_started($set = NULL) {
  * @ingroup php_wrappers
  */
 function drupal_session_regenerate() {
-  global $user;
+  $user = \Drupal::currentUser();
 
   // Nothing to do if we are not allowed to change the session.
   if (!drupal_save_session()) {
@@ -414,9 +414,11 @@ function drupal_session_regenerate() {
     // Start the session when it doesn't exist yet.
     // Preserve the logged in user, as it will be reset to anonymous
     // by _drupal_session_read.
-    $account = $user;
-    drupal_session_start();
-    $user = $account;
+    if ($user->hasAccount()) {
+      $account = $user->getAccount();
+      drupal_session_start();
+      $user->setAccount($account);
+    }
   }
   date_default_timezone_set(drupal_get_user_timezone());
 }
@@ -430,7 +432,7 @@ function drupal_session_regenerate() {
  *   Session ID.
  */
 function _drupal_session_destroy($sid) {
-  global $user;
+  $user = \Drupal::currentUser();
 
   // Nothing to do if we are not allowed to change the session.
   if (!drupal_save_session()) {
@@ -446,7 +448,7 @@ function _drupal_session_destroy($sid) {
   // Reset $_SESSION and $user to prevent a new session from being started
   // in drupal_session_commit().
   $_SESSION = array();
-  $user = drupal_anonymous_user();
+  $user->setAccount(drupal_anonymous_user());
 
   // Unset the session cookies.
   _drupal_session_delete_cookie(session_name());
diff --git a/core/lib/Drupal/Core/Authentication/AccountProxy.php b/core/lib/Drupal/Core/Authentication/AccountProxy.php
new file mode 100644
index 0000000..c99f1ef
--- /dev/null
+++ b/core/lib/Drupal/Core/Authentication/AccountProxy.php
@@ -0,0 +1,231 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Authentication\AccountProxy.
+ */
+
+namespace Drupal\Core\Authentication;
+
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * A proxied implementation of AccountInterface.
+ */
+class AccountProxy implements AccountInterface {
+
+  /**
+   * The current request.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
+
+  /**
+   * The authentication manager.
+   *
+   * @var \Drupal\Core\Authentication\AuthenticationManagerInterface
+   */
+  protected $authenticationManager;
+
+  /**
+   * The instantiated account.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $account;
+
+  /**
+   * Constructs a new AccountProxy.
+   *
+   * @param \Drupal\Core\Authentication\AuthenticationManagerInterface $authentication_manager
+   *   The authentication manager.
+   */
+  public function __construct(AuthenticationManagerInterface $authentication_manager) {
+    $this->authenticationManager = $authentication_manager;
+  }
+
+  /**
+   * Sets the current request.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request.
+   */
+  public function setRequest(Request $request) {
+    $this->request = $request;
+    // Reset the current user to ensure that new calls will return the correct
+    // user based on the request.
+    $this->account = NULL;
+  }
+
+  /**
+   * Set the current wrapped account.
+   *
+   * @param \Drupal\Core\Session\AccountInterface
+   *   The current account.
+   */
+  public function setAccount(AccountInterface $account) {
+    // If the passed account is already proxied, use the actual account instead
+    // to prevent loops.
+    if ($account instanceof static) {
+      $account = $account->getAccount();
+    }
+    $this->account = $account;
+  }
+
+  /**
+   * Gets the current account.
+   *
+   * @return \Drupal\Core\Session\AccountInterface
+   *   The current account.
+   */
+  public function getAccount() {
+    if (!isset($this->account)) {
+      $this->setAccount($this->authenticationManager->authenticate($this->request));
+    }
+    return $this->account;
+  }
+
+  public function hasAccount() {
+    return isset($this->account);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function id() {
+    return $this->getAccount()->id();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRoles() {
+    return $this->getAccount()->getRoles();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasPermission($permission) {
+    return $this->getAccount()->hasPermission($permission);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSessionId() {
+    return $this->getAccount()->getSessionId();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSecureSessionId() {
+    return $this->getAccount()->getSecureSessionId();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSessionData() {
+    return $this->getAccount()->getSessionData();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isAuthenticated() {
+    return $this->hasAccount() && $this->getAccount()->isAuthenticated();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isAnonymous() {
+    return $this->getAccount()->isAnonymous();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPreferredLangcode($default = NULL) {
+    return $this->getAccount()->getPreferredLangcode($default);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPreferredAdminLangcode($default = NULL) {
+    return $this->getAccount()->getPreferredAdminLangcode($default);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getUsername() {
+    return $this->getAccount()->getUsername();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getEmail() {
+    return $this->getAccount()->getEmail();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTimeZone() {
+    return $this->getAccount()->getTimeZone();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLastAccessedTime() {
+    return $this->getAccount()->getLastAccessedTime();
+  }
+
+  /**
+   * Implements the magic method for getting object properties.
+   */
+  public function &__get($name) {
+    return $this->getAccount()->{$name};
+  }
+
+  /**
+   * Implements the magic method for setting object properties.
+   */
+  public function __set($name, $value) {
+    if ($name == '_serviceId') {
+      $this->{$name} = $value;
+      return;
+    }
+    $this->getAccount()->{$name} = $value;
+  }
+
+  /**
+   * Implements the magic method for isset().
+   */
+  public function __isset($name) {
+    if ($name == 'account') {
+      return $this->account !== NULL;
+      return isset($this->account);
+    }
+    else {
+      return isset($this->getAccount()->{$name});
+    }
+  }
+
+  /**
+   * Implements the magic method for unset.
+   */
+  public function __unset($name) {
+    unset($this->getAccount()->{$name});
+  }
+
+}
+
diff --git a/core/lib/Drupal/Core/Authentication/AuthenticationManager.php b/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
index 672516a..ca22586 100644
--- a/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
+++ b/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
@@ -83,8 +83,6 @@ public function applies(Request $request) {
    * {@inheritdoc}
    */
   public function authenticate(Request $request) {
-    global $user;
-
     $account = NULL;
 
     // Iterate the availlable providers.
@@ -100,6 +98,7 @@ public function authenticate(Request $request) {
     // No provider returned a valid account, so set the user to anonymous.
     if (!$account) {
       $account = drupal_anonymous_user();
+      $provider->authenticate($request);
     }
 
     // No provider was fired, so assume the one with the least priority
@@ -114,9 +113,6 @@ public function authenticate(Request $request) {
 
     // The global $user object is included for backward compatibility only and
     // should be considered deprecated.
-    // @todo Remove this line once global $user is no longer used.
-    $user = $account;
-
     return $account;
   }
 
diff --git a/core/lib/Drupal/Core/Authentication/AuthenticationManagerInterface.php b/core/lib/Drupal/Core/Authentication/AuthenticationManagerInterface.php
index b547edd..0b4c0ff 100644
--- a/core/lib/Drupal/Core/Authentication/AuthenticationManagerInterface.php
+++ b/core/lib/Drupal/Core/Authentication/AuthenticationManagerInterface.php
@@ -10,7 +10,7 @@
 /**
  * Defines an interface for authentication managers.
  */
-interface AuthenticationManagerInterface {
+interface AuthenticationManagerInterface extends AuthenticationProviderInterface {
 
   /**
    * Returns the service id of the default authentication provider.
@@ -19,4 +19,5 @@
    *   The service id of the default authentication provider.
    */
   public function defaultProviderId();
+
 }
diff --git a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php
index ae108dc..919413e 100644
--- a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php
+++ b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php
@@ -30,12 +30,12 @@ public function applies(Request $request) {
    * {@inheritdoc}
    */
   public function authenticate(Request $request) {
+    $user = \Drupal::currentUser();
     // Global $user is deprecated, but the session system is still based on it.
-    global $user;
     require_once DRUPAL_ROOT . '/' . settings()->get('session_inc', 'core/includes/session.inc');
     drupal_session_initialize();
-    if (drupal_session_started()) {
-      return $user;
+    if (drupal_session_started() && $user->hasAccount()) {
+      return $user->getAccount();
     }
     return NULL;
   }
diff --git a/core/lib/Drupal/Core/Cron.php b/core/lib/Drupal/Core/Cron.php
index 1fe9727..6cb65a9 100644
--- a/core/lib/Drupal/Core/Cron.php
+++ b/core/lib/Drupal/Core/Cron.php
@@ -78,10 +78,8 @@ public function run() {
 
     // Force the current user to anonymous to ensure consistent permissions on
     // cron runs.
-    // @todo This currently does not work, as it will not affect the current
-    //   user being injected into services.
-    $original_user = $GLOBALS['user'];
-    $GLOBALS['user'] = new UserSession();
+    $original_user = \Drupal::currentUser();
+    \Drupal::currentUser()->setAccount(new UserSession());
 
     // Try to allocate enough time to run all the hook_cron implementations.
     drupal_set_time_limit(240);
@@ -147,9 +145,7 @@ public function run() {
     }
 
     // Restore the user.
-    // @todo This currently does not work, as it will not affect the current
-    //   user being injected into services.
-    $GLOBALS['user'] = $original_user;
+    \Drupal::currentUser()->setAccount($original_user);
     drupal_save_session($original_session_saving);
 
     return $return;
diff --git a/core/lib/Drupal/Core/Entity/EntityAccessController.php b/core/lib/Drupal/Core/Entity/EntityAccessController.php
index 835bb5a..b43c112 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessController.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessController.php
@@ -269,7 +269,7 @@ protected function checkCreateAccess(AccountInterface $account, array $context,
    */
   protected function prepareUser(AccountInterface $account = NULL) {
     if (!$account) {
-      $account = $GLOBALS['user'];
+      $account = \Drupal::currentUser();
     }
     return $account;
   }
diff --git a/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php
index a2aa7d8..04508be 100644
--- a/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php
@@ -40,18 +40,6 @@ public function __construct(AuthenticationProviderInterface $authentication_prov
   }
 
   /**
-   * Authenticates user on request.
-   *
-   * @see \Drupal\Core\Authentication\AuthenticationProviderInterface::authenticate()
-   */
-  public function onKernelRequestAuthenticate(GetResponseEvent $event) {
-    if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
-      $request = $event->getRequest();
-      $this->authenticationProvider->authenticate($request);
-    }
-  }
-
-  /**
    * Triggers authentication clean up on response.
    *
    * @see \Drupal\Core\Authentication\AuthenticationProviderInterface::cleanup()
@@ -83,9 +71,6 @@ public function onException(GetResponseForExceptionEvent $event) {
    * Cookie provider to send all relevant session data to the user.
    */
   public static function getSubscribedEvents() {
-    // Priority must be higher than LanguageRequestSubscriber as LanguageManager
-    // access current user in case language module enabled.
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestAuthenticate', 300);
     $events[KernelEvents::RESPONSE][] = array('onRespond', 0);
     $events[KernelEvents::EXCEPTION][] = array('onException', 0);
     return $events;
diff --git a/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php b/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php
index 6e577b9..14b2716 100644
--- a/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php
+++ b/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php
@@ -54,7 +54,7 @@ public function enhance(array $defaults, Request $request) {
       if (!in_array($auth_provider_triggered, $auth_providers)) {
         $anonymous_user = drupal_anonymous_user();
 
-        $this->container->set('current_user', $anonymous_user, 'request');
+        $this->container->get('current_user')->setAccount($anonymous_user);
 
         // The global $user object is included for backward compatibility only
         // and should be considered deprecated.
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php
index 0178a25..19f5035 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php
@@ -120,7 +120,7 @@ public function testNodeHandler() {
 
     // Test as a non-admin.
     $normal_user = $this->drupalCreateUser(array('access content'));
-    $this->container->set('current_user', $normal_user);
+    \Drupal::currentUser()->setAccount($normal_user);
     $referenceable_tests = array(
       array(
         'arguments' => array(
@@ -172,7 +172,7 @@ public function testNodeHandler() {
 
     // Test as an admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'bypass node access'));
-    $this->container->set('current_user', $admin_user);
+    \Drupal::currentUser()->setAccount($admin_user);
     $referenceable_tests = array(
       array(
         'arguments' => array(
@@ -266,7 +266,7 @@ public function testUserHandler() {
     }
 
     // Test as a non-admin.
-    $this->container->set('current_user', $users['non_admin']);
+    \Drupal::currentUser()->setAccount($users['non_admin']);
     $referenceable_tests = array(
       array(
         'arguments' => array(
@@ -305,7 +305,7 @@ public function testUserHandler() {
     );
     $this->assertReferenceable($instance, $referenceable_tests, 'User handler');
 
-    $this->container->set('current_user', $users['admin']);
+    \Drupal::currentUser()->setAccount($users['admin']);
     $referenceable_tests = array(
       array(
         'arguments' => array(
@@ -447,7 +447,7 @@ public function testCommentHandler() {
 
     // Test as a non-admin.
     $normal_user = $this->drupalCreateUser(array('access content', 'access comments'));
-    $this->container->set('current_user', $normal_user);
+    \Drupal::currentUser()->setAccount($normal_user);
     $referenceable_tests = array(
       array(
         'arguments' => array(
@@ -486,7 +486,7 @@ public function testCommentHandler() {
 
     // Test as a comment admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments'));
-    $this->container->set('current_user', $admin_user);
+    \Drupal::currentUser()->setAccount($admin_user);
     $referenceable_tests = array(
       array(
         'arguments' => array(
@@ -504,7 +504,7 @@ public function testCommentHandler() {
 
     // Test as a node and comment admin.
     $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access'));
-    $this->container->set('current_user', $admin_user);
+    \Drupal::currentUser()->setAccount($admin_user);
     $referenceable_tests = array(
       array(
         'arguments' => array(
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
index fbd4461..06f0a69 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php
@@ -120,7 +120,7 @@ public function testSort() {
 
     // Test as a non-admin.
     $normal_user = $this->drupalCreateUser(array('access content'));
-    $this->container->set('current_user', $normal_user);
+    \Drupal::currentUser()->setAccount($normal_user);
 
     $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($instance);
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileManagedUnitTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileManagedUnitTestBase.php
index 324b1b5..c9ec86d 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileManagedUnitTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileManagedUnitTestBase.php
@@ -37,7 +37,7 @@ function setUp() {
     $user = entity_create('user', array('uid' => 1, 'name' => $this->randomName()));
     $user->enforceIsNew();
     $user->save();
-    $this->container->set('current_user', $user);
+    \Drupal::currentUser()->setAccount($user);
   }
 
   /**
diff --git a/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php b/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php
index f054602..398860c 100644
--- a/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/ValidatorTest.php
@@ -133,7 +133,7 @@ function testFileValidateSize() {
     $user = entity_create('user', array('uid' => 2, 'name' => $this->randomName()));
     $user->enforceIsNew();
     $user->save();
-    $this->container->set('current_user', $user);
+    \Drupal::currentUser()->setAccount($user);
 
     // Create a file with a size of 1000 bytes, and quotas of only 1 byte.
     $file = entity_create('file', array('filesize' => 1000));
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php
index c36b009..0f9c4fc 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterAPITest.php
@@ -206,7 +206,7 @@ function testTypedDataAPI() {
 
     // Test with anonymous user.
     $user = drupal_anonymous_user();
-    $this->container->set('current_user', $user);
+    \Drupal::currentUser()->setAccount($user);
 
     $expected_available_options = array(
       'filtered_html' => 'Filtered HTML',
@@ -245,7 +245,7 @@ function testTypedDataAPI() {
     $this->assertFilterFormatViolation($violations, 'filtered_html');
 
     // Set user with access to 'filtered_html' format.
-    $this->container->set('current_user', $filtered_html_user);
+    \Drupal::currentUser()->setAccount($filtered_html_user);
     $violations = $data->validate();
     $this->assertEqual(count($violations), 0, "No validation violation for accessible format 'filtered_html' found.");
 
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index 1ab979f..45aa93d 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -1028,7 +1028,7 @@ private function prepareEnvironment() {
     // simpletest directory if a test is executed within a test.
     $this->originalFileDirectory = settings()->get('file_public_path', conf_path() . '/files');
     $this->originalProfile = drupal_get_profile();
-    $this->originalUser = isset($user) ? clone $user : NULL;
+    $this->originalUser = $user->hasAccount() ? clone $user->getAccount() : NULL;
 
     // Ensure that the current session is not changed by the new environment.
     require_once DRUPAL_ROOT . '/' . settings()->get('session_inc', 'core/includes/session.inc');
@@ -1090,7 +1090,7 @@ private function prepareEnvironment() {
 
     // Run all tests as a anonymous user by default, web tests will replace that
     // during the test set up.
-    $this->container->set('current_user', drupal_anonymous_user());
+    \Drupal::currentUser()->setAccount(drupal_anonymous_user());
 
     \Drupal::setContainer($this->container);
 
@@ -1149,7 +1149,7 @@ protected function rebuildContainer($environment = 'testing') {
     $this->container = \Drupal::getContainer();
     // The current user is set in TestBase::prepareEnvironment().
     $this->container->set('request', $request);
-    $this->container->set('current_user', \Drupal::currentUser());
+    $this->container->get('current_user')->setAccount(\Drupal::currentUser());
   }
 
   /**
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 8efa40a..8fe2fe9 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -680,7 +680,7 @@ protected function drupalLogin(AccountInterface $account) {
     $pass = $this->assert($this->drupalUserIsLoggedIn($account), format_string('User %name successfully logged in.', array('%name' => $account->getUsername())), 'User login');
     if ($pass) {
       $this->loggedInUser = $account;
-      $this->container->set('current_user', $account);
+      $this->container->get('current_user')->setAccount($account);
       // @todo Temporary workaround for not being able to use synchronized
       //   services in non dumped container.
       $this->container->get('access_subscriber')->setCurrentUser($account);
@@ -728,7 +728,7 @@ protected function drupalLogout() {
       // @see WebTestBase::drupalUserIsLoggedIn()
       unset($this->loggedInUser->session_id);
       $this->loggedInUser = FALSE;
-      $this->container->set('current_user', drupal_anonymous_user());
+      $this->container->get('current_user')->setAccount(drupal_anonymous_user());
     }
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php
index ee64237..296b32f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityAccessTest.php
@@ -49,8 +49,7 @@ function assertEntityAccess($ops, AccessibleInterface $object, AccountInterface
    */
   function testEntityAccess() {
     // Set up a non-admin user that is allowed to view test entities.
-    global $user;
-    $user = $this->createUser(array('uid' => 2), array('view test entity'));
+    \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2), array('view test entity')));
     $entity = entity_create('entity_test', array(
       'name' => 'test',
     ));
@@ -78,8 +77,7 @@ function testEntityAccess() {
    */
   function testEntityAccessDefaultController() {
     // The implementation requires that the global user id can be loaded.
-    global $user;
-    $user = $this->createUser(array('uid' => 2));
+    \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2)));
 
     // Check that the default access controller is used for entities that don't
     // have a specific access controller defined.
@@ -101,8 +99,7 @@ function testEntityAccessDefaultController() {
   function testEntityTranslationAccess() {
 
     // Set up a non-admin user that is allowed to view test entity translations.
-    global $user;
-    $user = $this->createUser(array('uid' => 2), array('view test entity translations'));
+    \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2), array('view test entity translations')));
 
     // Create two test languages.
     foreach (array('foo', 'bar') as $langcode) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php
index 0e6d629..6b17e88 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php
@@ -46,7 +46,7 @@ public function setUp() {
    * Tests the form cache with a logged-in user.
    */
   function testCacheToken() {
-    $this->container->set('current_user', new UserSession(array('uid' => 1)));
+    $this->container->get('current_user')->setAccount(new UserSession(array('uid' => 1)));
     form_set_cache($this->form_build_id, $this->form, $this->form_state);
 
     $cached_form_state = form_state_defaults();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php b/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php
index 16d3eec..00e42b6 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php
@@ -300,6 +300,7 @@ function assertSessionCookie($sent) {
    * Assert whether $_SESSION is empty at the beginning of the request.
    */
   function assertSessionEmpty($empty) {
+    debug($this->drupalGetHeader('X-Session-Empty'));
     if ($empty) {
       $this->assertIdentical($this->drupalGetHeader('X-Session-Empty'), '1', 'Session was empty.');
     }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
index 586e1eb..5013e5a 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
@@ -243,7 +243,7 @@ function testLinks() {
     $this->assertThemeOutput('links', $variables, $expected);
 
     // Verify the data- attributes for setting the "active" class on links.
-    $this->container->set('current_user', new UserSession(array('uid' => 1)));
+    $this->container->get('current_user')->setAccount(new UserSession(array('uid' => 1)));
     $variables['set_active_class'] = TRUE;
     $expected_links = '';
     $expected_links .= '<ul id="somelinks">';
diff --git a/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/TestContent.php b/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/TestContent.php
index 57a1a85..6559c70 100644
--- a/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/TestContent.php
+++ b/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/TestContent.php
@@ -58,9 +58,9 @@ public function test11() {
   }
 
   public function testAccount(UserInterface $user) {
-    $current_user = $this->currentUser();
-    \Drupal::getContainer()->set('current_user', $user);
-    return $current_user->getUsername() . ':' . $user->getUsername();
+    $current_user_name = $this->currentUser()->getUsername();
+    $this->currentUser()->setAccount($user);
+    return $current_user_name . ':' . $user->getUsername();
   }
 
   /**
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 5191c32..1bf27fe 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -805,8 +805,7 @@ function user_authenticate($name, $password) {
  * @see hook_user_login()
  */
 function user_login_finalize(UserInterface $account) {
-  global $user;
-  $user = $account;
+  \Drupal::currentUser()->setAccount($account);
   watchdog('user', 'Session opened for %name.', array('%name' => $account->getUsername()));
   // Update the user table timestamp noting user has logged in.
   // This is also used to invalidate one-time login links.
