diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
index 885db53..3559998 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
@@ -2,11 +2,12 @@
 
 /**
  * @file
- * Definition of Drupal\Core\EventSubscriber\MaintenanceModeSubscriber.
+ * Contains \Drupal\Core\EventSubscriber\MaintenanceModeSubscriber.
  */
 
 namespace Drupal\Core\EventSubscriber;
 
+use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -18,22 +19,29 @@
 class MaintenanceModeSubscriber implements EventSubscriberInterface {
 
   /**
-   * Response with the maintenance page when the site is offline.
+   * Determine whether the page is configured to be offline.
    *
-   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
    *   The Event to process.
    */
-  public function onKernelRequestMaintenanceModeCheck(GetResponseEvent $event) {
+  public function onKernelRequestDetermineSiteStatus(GetResponseEvent $event) {
     // Check if the site is offline.
-    $status = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
-
-    // Allow other modules to change the site status but not the path. The path
-    // can be changed using a request listener.
-    $read_only_path = $event->getRequest()->attributes->get('system_path');
-    drupal_alter('menu_site_status', $status, $read_only_path);
+    $request = $event->getRequest();
+    $is_offline = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
+    $request->attributes->set('_maintenance', $is_offline);
+  }
 
-    // Only continue if the site is online.
-    if ($status != MENU_SITE_ONLINE) {
+  /**
+   * Returns the site maintenance page if the site is offline.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The event to process.
+   */
+  public function onKernelRequestMaintenance(GetResponseEvent $event) {
+    $request = $event->getRequest();
+    $response = $event->getResponse();
+    // Continue if the site is online and the response is not a redirection.
+    if ($request->attributes->get('_maintenance') != MENU_SITE_ONLINE && !($response instanceof RedirectResponse)) {
       // Deliver the 503 page.
       drupal_maintenance_theme();
       drupal_set_title(t('Site under maintenance'));
@@ -45,13 +53,13 @@ public function onKernelRequestMaintenanceModeCheck(GetResponseEvent $event) {
   }
 
   /**
-   * Registers the methods in this class that should be listeners.
-   *
-   * @return array
-   *   An array of event listener definitions.
+   * {@inheritdoc}
    */
   static function getSubscribedEvents() {
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenanceModeCheck', 40);
+    // In order to change the maintenance status an event subscriber with a
+    // priority between 30 and 40 should be added.
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestDetermineSiteStatus', 40);
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 30);
     return $events;
   }
 }
diff --git a/core/modules/system/tests/modules/menu_test/lib/Drupal/menu_test/EventSubscriber/MaintenanceModeSubscriber.php b/core/modules/system/tests/modules/menu_test/lib/Drupal/menu_test/EventSubscriber/MaintenanceModeSubscriber.php
new file mode 100644
index 0000000..ae5f4df
--- /dev/null
+++ b/core/modules/system/tests/modules/menu_test/lib/Drupal/menu_test/EventSubscriber/MaintenanceModeSubscriber.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\menu_test\EventSubscriber\MaintenanceModeSubscriber.
+ */
+
+namespace Drupal\menu_test\EventSubscriber;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Maintenance mode subscriber to set site online on a test.
+ */
+class MaintenanceModeSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Set the page online if called from a certain path.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The event to process.
+   */
+  public function onKernelRequestMaintenance(GetResponseEvent $event) {
+    $request = $event->getRequest();
+    // Allow access to menu_login_callback even if in maintenance mode.
+    if ($request->attributes->get('_maintenance') == MENU_SITE_OFFLINE && $request->attributes->get('system_path') == 'menu_login_callback') {
+      $request->attributes->set('_maintenance', MENU_SITE_ONLINE);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 35);
+    return $events;
+  }
+
+}
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/system/tests/modules/menu_test/menu_test.module
index c5a0be6..6ad19ba 100644
--- a/core/modules/system/tests/modules/menu_test/menu_test.module
+++ b/core/modules/system/tests/modules/menu_test/menu_test.module
@@ -686,16 +686,6 @@ function menu_test_static_variable($value = NULL) {
 }
 
 /**
- * Implements hook_menu_site_status_alter().
- */
-function menu_test_menu_site_status_alter(&$menu_site_status, $path) {
-  // Allow access to menu_login_callback even if in maintenance mode.
-  if ($menu_site_status == MENU_SITE_OFFLINE && $path == 'menu_login_callback') {
-    $menu_site_status = MENU_SITE_ONLINE;
-  }
-}
-
-/**
  * Menu callback to be used as a login path.
  */
 function menu_login_callback() {
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.services.yml b/core/modules/system/tests/modules/menu_test/menu_test.services.yml
new file mode 100644
index 0000000..097ddf2
--- /dev/null
+++ b/core/modules/system/tests/modules/menu_test/menu_test.services.yml
@@ -0,0 +1,5 @@
+services:
+  menu_test_maintenance_mode_subscriber:
+    class: Drupal\menu_test\EventSubscriber\MaintenanceModeSubscriber
+    tags:
+      - { name: event_subscriber }
diff --git a/core/modules/user/lib/Drupal/user/Controller/UserController.php b/core/modules/user/lib/Drupal/user/Controller/UserController.php
index b310165..c6b0aae 100644
--- a/core/modules/user/lib/Drupal/user/Controller/UserController.php
+++ b/core/modules/user/lib/Drupal/user/Controller/UserController.php
@@ -11,7 +11,6 @@
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Drupal\Core\ControllerInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
 
 /**
  * Controller routines for user routes.
@@ -19,29 +18,16 @@
 class UserController implements ControllerInterface {
 
   /**
-   * The module handler service.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
    * Constructs an UserController object.
-   *
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler service.
    */
-  public function __construct(ModuleHandlerInterface $module_handler) {
-    $this->moduleHandler = $module_handler;
+  public function __construct() {
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('module_handler')
-    );
+  public static function create() {
+    return new static();
   }
 
   /**
@@ -54,12 +40,7 @@ public static function create(ContainerInterface $container) {
    *   A redirection to home page.
    */
   public function logout(Request $request) {
-    global $user;
-
-    watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
-    $this->moduleHandler->invokeAll('user_logout', array($user));
-    // Destroy the current session, and reset $user to the anonymous user.
-    session_destroy();
+    user_logout();
     // @todo Remove the destination check once drupal.org/node/1668866 is in.
     $url = $request->query->get('destination') ?: '<front>';
     return new RedirectResponse(url($url, array('absolute' => TRUE)));
diff --git a/core/modules/user/lib/Drupal/user/EventSubscriber/MaintenanceModeSubscriber.php b/core/modules/user/lib/Drupal/user/EventSubscriber/MaintenanceModeSubscriber.php
new file mode 100644
index 0000000..bfaee91
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/EventSubscriber/MaintenanceModeSubscriber.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\user\EventSubscriber\MaintenanceModeSubscriber.
+ */
+
+namespace Drupal\user\EventSubscriber;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Maintenance mode subscriber to logout users.
+ */
+class MaintenanceModeSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Determine whether the page is configured to be offline.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The event to process.
+   */
+  public function onKernelRequestMaintenance(GetResponseEvent $event) {
+    $request = $event->getRequest();
+    $site_status = $request->attributes->get('_maintenance');
+    $path = $request->attributes->get('system_path');
+    if ($site_status == MENU_SITE_OFFLINE) {
+      // If the site is offline, log out unprivileged users.
+      if (user_is_logged_in() && !user_access('access site in maintenance mode')) {
+        user_logout();
+        // Redirect to homepage.
+        $event->setResponse(new RedirectResponse(url('<front>', array('absolute' => TRUE))));
+        return;
+      }
+
+      if (user_is_anonymous()) {
+        switch ($path) {
+          case 'user':
+            // Forward anonymous user to login page.
+            $event->setResponse(new RedirectResponse(url('user/login', array('absolute' => TRUE))));
+            return;
+          case 'user/login':
+          case 'user/password':
+            // Disable offline mode.
+            $request->attributes->set('_maintenance', MENU_SITE_ONLINE);
+            break;
+          default:
+            if (strpos($path, 'user/reset/') === 0) {
+              // Disable offline mode.
+              $request->attributes->set('_maintenance', MENU_SITE_ONLINE);
+            }
+            break;
+        }
+      }
+    }
+    if (user_is_logged_in()) {
+      if ($path == 'user/login') {
+        // If user is logged in, redirect to 'user' instead of giving 403.
+        $event->setResponse(new RedirectResponse(url('user', array('absolute' => TRUE))));
+        return;
+      }
+      if ($path == 'user/register') {
+        // Authenticated user should be redirected to user edit page.
+        $event->setResponse(new RedirectResponse(url('user/' . $GLOBALS['user']->uid . '/edit', array('absolute' => TRUE))));
+        return;
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 35);
+    return $events;
+  }
+
+}
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index abfe84b..40dfd4f 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1038,48 +1038,6 @@ function user_menu() {
 }
 
 /**
- * Implements hook_menu_site_status_alter().
- */
-function user_menu_site_status_alter(&$menu_site_status, $path) {
-  if ($menu_site_status == MENU_SITE_OFFLINE) {
-    // If the site is offline, log out unprivileged users.
-    if (user_is_logged_in() && !user_access('access site in maintenance mode')) {
-      module_load_include('pages.inc', 'user', 'user');
-      user_logout();
-    }
-
-    if (user_is_anonymous()) {
-      switch ($path) {
-        case 'user':
-          // Forward anonymous user to login page.
-          drupal_goto('user/login');
-        case 'user/login':
-        case 'user/password':
-          // Disable offline mode.
-          $menu_site_status = MENU_SITE_ONLINE;
-          break;
-        default:
-          if (strpos($path, 'user/reset/') === 0) {
-            // Disable offline mode.
-            $menu_site_status = MENU_SITE_ONLINE;
-          }
-          break;
-      }
-    }
-  }
-  if (user_is_logged_in()) {
-    if ($path == 'user/login') {
-      // If user is logged in, redirect to 'user' instead of giving 403.
-      drupal_goto('user');
-    }
-    if ($path == 'user/register') {
-      // Authenticated user should be redirected to user edit page.
-      drupal_goto('user/' . $GLOBALS['user']->uid . '/edit');
-    }
-  }
-}
-
-/**
  * Implements hook_menu_link_presave().
  */
 function user_menu_link_presave(MenuLink $menu_link) {
@@ -2785,3 +2743,17 @@ function user_library_info() {
 
   return $libraries;
 }
+
+/**
+ * Logs the current user out.
+ */
+function user_logout() {
+  global $user;
+
+  watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
+
+  Drupal::moduleHandler()->invokeAll('user_logout', array($user));
+
+  // Destroy the current session, and reset $user to the anonymous user.
+  session_destroy();
+}
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index ed1e029..a59f1a0 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -170,22 +170,6 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
 }
 
 /**
- * Logs the current user out, and redirects to the home page.
- */
-function user_logout() {
-  global $user;
-
-  watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
-
-  module_invoke_all('user_logout', $user);
-
-  // Destroy the current session, and reset $user to the anonymous user.
-  session_destroy();
-
-  drupal_goto();
-}
-
-/**
  * Prepares variables for user templates.
  *
  * Default template: user.html.twig.
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 468955d..6fb7d47 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -21,3 +21,7 @@ services:
   user.autocomplete:
     class: Drupal\user\UserAutocomplete
     arguments: ['@database', '@config.factory']
+  user_maintenance_mode_subscriber:
+    class: Drupal\user\EventSubscriber\MaintenanceModeSubscriber
+    tags:
+      - { name: event_subscriber }
