diff --git a/core/modules/rest/tests/src/Unit/CollectRoutesTest.php b/core/modules/rest/tests/src/Unit/CollectRoutesTest.php
index 7a91831..ad4b7f8 100644
--- a/core/modules/rest/tests/src/Unit/CollectRoutesTest.php
+++ b/core/modules/rest/tests/src/Unit/CollectRoutesTest.php
@@ -137,7 +137,14 @@ public function testRoutesRequirements() {
     $requirements_1 = $this->routes->get('test_1')->getRequirements();
     $requirements_2 = $this->routes->get('view.test_view.page_1')->getRequirements();
 
-    $this->assertEquals(count($requirements_1), 0, 'First route has no requirement.');
-    $this->assertEquals(count($requirements_2), 2, 'Views route with rest export had the format and method requirements added.');
+    $this->assertEquals(0, count($requirements_1), 'First route has no requirement.');
+
+    $this->assertEquals(3, count($requirements_2), 'Views route with rest export had the format and method requirements added.');
+    $this->assertTrue(isset($requirements_2['_views_access_all_views']));
+    $this->assertEquals('TRUE', $requirements_2['_views_access_all_views']);
+    $this->assertTrue(isset($requirements_2['_method']));
+    $this->assertEquals('GET', $requirements_2['_method']);
+    $this->assertTrue(isset($requirements_2['_format']));
+    $this->assertEquals('json', $requirements_2['_format']);
   }
 }
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index f3d90ce..1af8f29 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -197,8 +197,12 @@ protected function getRoute($view_id, $display_id) {
       $access_plugin = Views::pluginManager('access')->createInstance('none');
     }
     $access_plugin->alterRouteDefinition($route);
-    // @todo Figure out whether _access_mode ANY is the proper one. This is
-    //   particular important for altering routes.
+
+    // Add in the access checker for accessing all views. The access mode must
+    // be 'ANY' for this to be combined with the view-specific access. We cannot
+    // use the generic _permission requirement, as that only allows one
+    // permission which must be reserved for the view-specific access.
+    $route->setRequirement('_views_access_all_views', 'TRUE');
     $route->setOption('_access_mode', AccessManagerInterface::ACCESS_MODE_ANY);
 
     // Set the argument map, in order to support named parameters.
diff --git a/core/modules/views/src/Tests/BulkOperationAccessTest.php b/core/modules/views/src/Tests/BulkOperationAccessTest.php
new file mode 100644
index 0000000..34bc727
--- /dev/null
+++ b/core/modules/views/src/Tests/BulkOperationAccessTest.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\views\Tests\BulkOperationAccessTest.
+ */
+
+namespace Drupal\views\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Ensure that account cancellation methods work as expected.
+ *
+ * @group user
+ */
+class BulkOperationAccessTest extends WebTestBase {
+
+  /**
+   * User with user admin permissions.
+   *
+   * @var \Drupal\user\Entity\User
+   */
+  protected $adminUser;
+
+
+  /**
+   * Regular user.
+   *
+   * @var \Drupal\user\Entity\User
+   */
+  protected $regularUser;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('views', 'views_bulk_access_test');
+
+  protected function setUp() {
+    parent::setUp();
+    $this->adminUser = $this->drupalCreateUser(array('administer users', 'access user profiles'));
+    $this->regularUser = $this->drupalCreateUser();
+  }
+
+  /**
+   * Tests that a user can't perform a forbidden action with bulk operations.
+   */
+  public function testViewsBulkOperationAccessCheck() {
+    $this->drupalLogin($this->adminUser);
+
+
+    $options = array('query' => array('user' => $this->regularUser->getUsername()));
+    $edit = array(
+      'action' => 'user_cancel_user_action',
+      'user_bulk_form[0]' => TRUE,
+    );
+    $this->drupalPostForm('admin/people', $edit, t('Apply'), $options);
+
+
+    $edit = array(
+      'accounts[' . $this->regularUser->id() . ']' => 'user_cancel_user_action',
+      'operation' => 'cancel',
+      'user_cancel_method' => 'user_cancel_delete',
+      'confirm' => TRUE,
+    );
+    $this->drupalPostForm('admin/people/cancel', $edit, t('Cancel accounts'));
+    $this->assertNotNull(\Drupal\user\Entity\User::load($this->regularUser->id()), 'The user is still exists.');
+  }
+
+}
diff --git a/core/modules/views/src/ViewsAccessCheck.php b/core/modules/views/src/ViewsAccessCheck.php
index 62f68a6..455ea9d 100644
--- a/core/modules/views/src/ViewsAccessCheck.php
+++ b/core/modules/views/src/ViewsAccessCheck.php
@@ -9,22 +9,14 @@
 
 use Drupal\Core\Access\AccessCheckInterface;
 use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
 use Symfony\Component\Routing\Route;
 
 /**
- * Defines a route access checker for the _access_all_views permission.
- *
- * @todo We could leverage the permission one as well?
+ * Defines a route access checker for the 'access all views' permission.
  */
-class ViewsAccessCheck implements AccessCheckInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applies(Route $route) {
-    return $route->hasDefault('view_id');
-  }
+class ViewsAccessCheck implements AccessInterface {
 
   /**
    * Checks access.
diff --git a/core/modules/views/tests/modules/views_bulk_access_test/views_bulk_access_test.info.yml b/core/modules/views/tests/modules/views_bulk_access_test/views_bulk_access_test.info.yml
new file mode 100644
index 0000000..f3d214f
--- /dev/null
+++ b/core/modules/views/tests/modules/views_bulk_access_test/views_bulk_access_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Bulk Access Aest'
+type: module
+description: 'Support module for views bulk operations access testing.'
+package: Testi
+version: VERSION
+core: 8.x
diff --git a/core/modules/views/tests/modules/views_bulk_access_test/views_bulk_access_test.module b/core/modules/views/tests/modules/views_bulk_access_test/views_bulk_access_test.module
new file mode 100644
index 0000000..8b0d83a
--- /dev/null
+++ b/core/modules/views/tests/modules/views_bulk_access_test/views_bulk_access_test.module
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @file
+ * Support module for testing bulk operation access check.
+ */
+
+use Drupal\Core\Access\AccessResultForbidden;
+
+/**
+ * Implements hook_ENTITY_TYPE_access().
+ */
+function views_bulk_access_test_user_access($entity, $operation, $account) {
+  if ($operation == 'delete') {
+    return AccessResultForbidden::forbidden();
+  }
+}
diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml
index b66568f..a009e5a 100644
--- a/core/modules/views/views.services.yml
+++ b/core/modules/views/views.services.yml
@@ -76,6 +76,6 @@ services:
   views.route_access_check:
     class: Drupal\views\ViewsAccessCheck
     tags:
-      - { name: 'access_check' }
+      - { name: access_check, applies_to: _views_access_all_views }
   views.exposed_form_cache:
     class: Drupal\views\ExposedFormCache
