diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs
index 7dd43069db..0c8ef5ccfd 100644
--- a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs
+++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryLoggerExtensions.cs
@@ -51,8 +51,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
_responseCacheHeadersOverridenToNoCache = LoggerMessage.Define(
LogLevel.Warning,
8,
- "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache' to prevent " +
- "caching of this response. Any response that uses antiforgery should not be cached.");
+ "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " +
+ "'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery " +
+ "should not be cached.");
}
public static void ValidationFailed(this ILogger logger, string message)
diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs
index 755d8ae2f1..9677f7a793 100644
--- a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs
+++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs
@@ -243,8 +243,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
_logger.ReusedCookieToken();
}
- // Explicitly set the cache headers to 'no-cache'. This could override any user set value but this is fine
- // as a response with antiforgery token must never be cached.
SetDoNotCacheHeaders(httpContext);
}
@@ -367,14 +365,18 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
return antiforgeryFeature;
}
- private void SetDoNotCacheHeaders(HttpContext httpContext)
+ ///
+ /// Sets the 'Cache-Control' header to 'no-cache, no-store' and 'Pragma' header to 'no-cache' overriding any user set value.
+ ///
+ /// The .
+ protected virtual void SetDoNotCacheHeaders(HttpContext httpContext)
{
// Since antifogery token generation is not very obvious to the end users (ex: MVC's form tag generates them
// by default), log a warning to let users know of the change in behavior to any cache headers they might
// have set explicitly.
LogCacheHeaderOverrideWarning(httpContext.Response);
- httpContext.Response.Headers[HeaderNames.CacheControl] = "no-cache";
+ httpContext.Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store";
httpContext.Response.Headers[HeaderNames.Pragma] = "no-cache";
}
diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs
index 943eb94cb4..e9b56f1c91 100644
--- a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs
+++ b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs
@@ -19,8 +19,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
public class DefaultAntiforgeryTest
{
private const string ResponseCacheHeadersOverrideWarningMessage =
- "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache' to prevent caching " +
- "of this response. Any response that uses antiforgery should not be cached.";
+ "The 'Cache-Control' and 'Pragma' headers have been overridden and set to 'no-cache, no-store' and " +
+ "'no-cache' respectively to prevent caching of this response. Any response that uses antiforgery " +
+ "should not be cached.";
[Fact]
public async Task ChecksSSL_ValidateRequestAsync_Throws()
@@ -308,7 +309,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(antiforgeryFeature);
Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
- Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.CacheControl]);
+ Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers[HeaderNames.CacheControl]);
Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]);
}
@@ -339,7 +340,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(antiforgeryFeature);
Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
- Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.CacheControl]);
+ Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers[HeaderNames.CacheControl]);
Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]);
}
@@ -403,7 +404,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(antiforgeryFeature);
Assert.True(antiforgeryFeature.HaveDeserializedCookieToken);
Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken);
- Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.CacheControl]);
+ Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers[HeaderNames.CacheControl]);
Assert.Equal("no-cache", context.HttpContext.Response.Headers[HeaderNames.Pragma]);
}
@@ -925,7 +926,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert
- Assert.Equal("no-cache", context.HttpContext.Response.Headers["Cache-Control"]);
+ Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers["Cache-Control"]);
Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]);
}
@@ -948,7 +949,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert
- Assert.Equal("no-cache", context.HttpContext.Response.Headers["Cache-Control"]);
+ Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers["Cache-Control"]);
Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]);
}
@@ -972,7 +973,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert
- Assert.Equal("no-cache", context.HttpContext.Response.Headers["Cache-Control"]);
+ Assert.Equal("no-cache, no-store", context.HttpContext.Response.Headers["Cache-Control"]);
Assert.Equal("no-cache", context.HttpContext.Response.Headers["Pragma"]);
}