diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc
index 9921e7b94b30e4c8f47a534e46f52e4cbff9b94e..b2ea67a00b08eccc5048c6a3ca3df63ebcf06c5d 100644
--- a/core/modules/image/image.admin.inc
+++ b/core/modules/image/image.admin.inc
@@ -58,6 +58,11 @@ function template_preprocess_image_style_preview(&$variables) {
     $style->createDerivative($original_path, $preview_file);
   }
   $preview_image = $image_factory->get($preview_file);
+
+  // Generate an itok.
+  $defaultScheme = \Drupal::config('system.file')->get('default_scheme');
+  $variables['itok'] = $style->getPathToken($defaultScheme . '://' . $original_path);
+
   $variables['derivative'] = [
     'url' => $file_url_generator->generateString($preview_file),
     'width' => $preview_image->getWidth(),
@@ -89,7 +94,7 @@ function template_preprocess_image_style_preview(&$variables) {
   // to prevent caching of images on the client side.
   $variables['derivative']['rendered'] = [
     '#theme' => 'image',
-    '#uri' => $variables['derivative']['url'] . '?cache_bypass=' . $variables['cache_bypass'],
+    '#uri' => $variables['derivative']['url'] . '?cache_bypass=' . $variables['cache_bypass'] . '&itok=' . $variables['itok'],
     '#alt' => t('Sample modified image'),
     '#title' => '',
     '#attributes' => [
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index ccd4c3e2c4011887ca23a03d5e864a27e8778a89..4203045b5952b4b02e8a3c9aa79e935f3a791acb 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -167,6 +167,20 @@ function image_file_download($uri) {
     }
     return -1;
   }
+
+  // If it is the sample image we need to grant access.
+  $samplePath = \Drupal::config('image.settings')->get('preview_image');
+  if ($path === $samplePath) {
+    $image = \Drupal::service('image.factory')->get($samplePath);
+    return [
+      // Send headers describing the image's size, and MIME-type.
+      'Content-Type' => $image->getMimeType(),
+      'Content-Length' => $image->getFileSize(),
+      // By not explicitly setting them here, this uses normal Drupal
+      // Expires, Cache-Control and ETag headers to prevent proxy or
+      // browser caching of private images.
+    ];
+  }
 }
 
 /**
diff --git a/core/modules/image/src/Controller/ImageStyleDownloadController.php b/core/modules/image/src/Controller/ImageStyleDownloadController.php
index 1df6ef1d42ff27c72cfccbf1e25826340d8e2e30..47b5681f1a9657cf086a859f4f90ef151026c9c7 100644
--- a/core/modules/image/src/Controller/ImageStyleDownloadController.php
+++ b/core/modules/image/src/Controller/ImageStyleDownloadController.php
@@ -110,6 +110,7 @@ public function deliver(Request $request, $scheme, ImageStyleInterface $image_st
     $target = $request->query->get('file');
     $image_uri = $scheme . '://' . $target;
     $image_uri = $this->streamWrapperManager->normalizeUri($image_uri);
+    $sample_image_uri = $scheme . '://' . $this->config('image.settings')->get('preview_image');
 
     if ($this->streamWrapperManager->isValidScheme($scheme)) {
       $normalized_target = $this->streamWrapperManager->getTarget($image_uri);
@@ -175,6 +176,11 @@ public function deliver(Request $request, $scheme, ImageStyleInterface $image_st
       }
     }
 
+    // If it is default sample.png, ignore scheme.
+    if ($image_uri === $sample_image_uri) {
+      $image_uri = $target;
+    }
+
     // Don't try to generate file if source is missing.
     if (!$this->sourceImageExists($image_uri, $token_is_valid)) {
       // If the image style converted the extension, it has been added to the
diff --git a/core/modules/image/tests/src/Functional/ImageAdminStylesTest.php b/core/modules/image/tests/src/Functional/ImageAdminStylesTest.php
index b603c95021771ba95f43a19c9adfa329d3425f84..b0de9171e35a70d3c4cbda7d1c56f084ae9b1edd 100644
--- a/core/modules/image/tests/src/Functional/ImageAdminStylesTest.php
+++ b/core/modules/image/tests/src/Functional/ImageAdminStylesTest.php
@@ -518,4 +518,38 @@ public function testImageStyleAccess() {
     $this->assertSession()->pageTextContains("Select a new effect");
   }
 
+  /**
+   * Tests the display of preview images using a private scheme.
+   */
+  public function testPreviewImageShowInPrivateScheme(): void {
+    $this->config('system.file')->set('default_scheme', 'private')->save();
+
+    /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */
+    $file_url_generator = \Drupal::service('file_url_generator');
+
+    // Get the original preview image file in core config.
+    $original_path = $this->config('image.settings')->get('preview_image');
+    $style = ImageStyle::create(['name' => 'test_foo', 'label' => 'test foo']);
+    $style->save();
+
+    // Build the derivative preview image file with the Image Style.
+    // @see template_preprocess_image_style_preview()
+    $preview_file = $style->buildUri($original_path);
+    $style->createDerivative($original_path, $preview_file);
+
+    // Check if the derivative image exists.
+    $this->assertFileExists($preview_file);
+
+    // Generate itok token for the preview image.
+    $itok = $style->getPathToken('private://' . $original_path);
+
+    $url = $file_url_generator->generateAbsoluteString($preview_file);
+    $url .= '?itok=' . $itok;
+
+    // Check if the preview image with style is shown.
+    $this->drupalGet($url);
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->responseHeaderContains('Content-Type', 'image/png');
+  }
+
 }