diff --git a/masquerade.services.yml b/masquerade.services.yml
index fb68166..b54cedf 100644
--- a/masquerade.services.yml
+++ b/masquerade.services.yml
@@ -15,7 +15,7 @@ services:
     arguments: ['@masquerade']
     tags:
       - { name: access_check, applies_to: _user_is_masquerading }
-  cache_context.is_masquerading:
+  cache_context.session.is_masquerading:
     class: Drupal\masquerade\Cache\MasqueradeCacheContext
     arguments: ['@request_stack']
     tags:
diff --git a/src/Access/SwitchAccessCheck.php b/src/Access/SwitchAccessCheck.php
index 260caa5..a1907cb 100644
--- a/src/Access/SwitchAccessCheck.php
+++ b/src/Access/SwitchAccessCheck.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @file
  * Contains \Drupal\masquerade\Access\SwitchAccessCheck.
@@ -10,7 +11,6 @@ use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\masquerade\Masquerade;
-use Drupal\user\Entity\Role;
 
 /**
  * Checks access for any masquerade permissions.
@@ -44,12 +44,20 @@ class SwitchAccessCheck implements AccessInterface {
    *   The access result.
    */
   public function access(AccountInterface $account) {
-    // Uid 1 may masquerade as anyone.
-    if ($account->id() == 1) {
-      return AccessResult::allowed()->cachePerUser();
+    if ($this->masquerade->isMasquerading()) {
+      // Do now allow to masquerade when already masquerading.
+      $result = AccessResult::forbidden();
+    }
+    elseif ($account->id() == 1) {
+      // Uid 1 may masquerade as anyone.
+      $result = AccessResult::allowed();
+    }
+    else {
+      // Ability to masquerade defined by permissions.
+      $permissions = $this->masquerade->getPermissions();
+      $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
     }
-    $permissions = $this->masquerade->getPermissions();
-    return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+    return $result->addCacheContexts(['session.is_masquerading']);
   }
 
 }
diff --git a/src/Access/UnmasqueradeAccessCheck.php b/src/Access/UnmasqueradeAccessCheck.php
index 83ae118..a6a9b52 100644
--- a/src/Access/UnmasqueradeAccessCheck.php
+++ b/src/Access/UnmasqueradeAccessCheck.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @file
  * Contains \Drupal\masquerade\Access\UnmasqueradeAccessCheck.
@@ -40,7 +41,7 @@ class UnmasqueradeAccessCheck implements AccessInterface {
    */
   public function access() {
     return AccessResult::allowedIf($this->masquerade->isMasquerading())
-      ->addCacheContexts(['is_masquerading']);
+      ->addCacheContexts(['session.is_masquerading']);
   }
 
 }
diff --git a/src/Cache/MasqueradeCacheContext.php b/src/Cache/MasqueradeCacheContext.php
index 6d1aae6..87796b8 100644
--- a/src/Cache/MasqueradeCacheContext.php
+++ b/src/Cache/MasqueradeCacheContext.php
@@ -15,7 +15,7 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 /**
  * Defines the MasqueradeCacheContext service, for "masquerade" caching.
  *
- * Cache context ID: 'is_masquerading'.
+ * Cache context ID: 'session.is_masquerading'.
  */
 class MasqueradeCacheContext extends RequestStackCacheContextBase implements CacheContextInterface {
 
@@ -30,10 +30,7 @@ class MasqueradeCacheContext extends RequestStackCacheContextBase implements Cac
    * {@inheritdoc}
    */
   public function getContext() {
-    return $this->requestStack
-      ->getCurrentRequest()
-      ->getSession()
-      ->has('masquerading');
+    return !empty($_SESSION['masquerading']) ? '1' : '0';
   }
 
   /**
diff --git a/src/Plugin/Block/MasqueradeBlock.php b/src/Plugin/Block/MasqueradeBlock.php
index 3669dd1..f8a83cf 100644
--- a/src/Plugin/Block/MasqueradeBlock.php
+++ b/src/Plugin/Block/MasqueradeBlock.php
@@ -80,17 +80,18 @@ class MasqueradeBlock extends BlockBase implements ContainerFactoryPluginInterfa
    */
   protected function blockAccess(AccountInterface $account) {
     if ($this->masquerade->isMasquerading()) {
-      return AccessResult::forbidden()->addCacheContexts(['is_masquerading']);
+      return AccessResult::forbidden()->addCacheContexts(['session.is_masquerading']);
     }
     // Display block for all users that has any of masquerade permissions.
-    return AccessResult::allowedIfHasPermissions($account, $this->masquerade->getPermissions(), 'OR');
+    return AccessResult::allowedIfHasPermissions($account, $this->masquerade->getPermissions(), 'OR')
+      ->addCacheContexts(['session.is_masquerading']);
   }
 
   /**
    * {@inheritdoc}
    */
   public function getCacheContexts() {
-    return Cache::mergeContexts(parent::getCacheContexts(), ['is_masquerading']);
+    return Cache::mergeContexts(parent::getCacheContexts(), ['session.is_masquerading']);
   }
 
   /**
diff --git a/src/Tests/MasqueradeCacheTest.php b/src/Tests/MasqueradeCacheTest.php
new file mode 100644
index 0000000..cc75356
--- /dev/null
+++ b/src/Tests/MasqueradeCacheTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\masquerade\Tests\MasqueradeCacheTest.
+ */
+
+namespace Drupal\masquerade\Tests;
+
+/**
+ * Tests caching for masquerade.
+ *
+ * @group masquerade
+ */
+class MasqueradeCacheTest extends MasqueradeWebTestBase {
+
+  public static $modules = ['masquerade', 'user', 'block', 'node', 'dynamic_page_cache'];
+
+  /**
+   * Tests caching for the user switch block.
+   */
+  function testMasqueradeSwitchBlockCaching() {
+    // Create two masquerade users.
+    $umberto = $this->drupalCreateUser(['masquerade as any user', 'access content'], 'umberto');
+    $nelle = $this->drupalCreateUser(['masquerade as any user', 'access content'], 'nelle');
+
+    // Add the Masquerade block to the sidebar.
+    $masquerade_block = $this->drupalPlaceBlock('masquerade');
+
+    // Login as Umberto.
+    $this->drupalLogin($umberto);
+    $this->drupalGet('<front>');
+    $this->assertBlockAppears($masquerade_block);
+
+    // Masquerade as Nelle.
+    $edit = ['masquerade_as' => $nelle->getAccountName()];
+    $this->drupalPostForm(NULL, $edit, t('Switch'));
+    $this->drupalGet('<front>');
+    $this->assertNoBlockAppears($masquerade_block);
+
+    // Logout, and log in as Nelle.
+    $this->drupalLogout();
+    $this->drupalLogin($nelle);
+    $this->drupalGet('<front>');
+    $this->assertBlockAppears($masquerade_block);
+  }
+
+}
