diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs
index 701855e913a3..ef7688e153aa 100644
--- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs
+++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs
@@ -187,7 +187,8 @@ private RequestDelegate BuildErrorPageApplication(Exception exception)
return context =>
{
context.Response.StatusCode = 500;
- context.Response.Headers[HeaderNames.CacheControl] = "no-cache";
+ context.Response.Headers[HeaderNames.CacheControl] = "no-cache,no-store";
+ context.Response.Headers[HeaderNames.Pragma] = "no-cache";
context.Response.ContentType = "text/html; charset=utf-8";
return errorPage.ExecuteAsync(context);
};
diff --git a/src/Hosting/Hosting/src/Internal/WebHost.cs b/src/Hosting/Hosting/src/Internal/WebHost.cs
index b016f751a887..060b3fd9a7e1 100644
--- a/src/Hosting/Hosting/src/Internal/WebHost.cs
+++ b/src/Hosting/Hosting/src/Internal/WebHost.cs
@@ -284,7 +284,8 @@ private RequestDelegate BuildApplication()
return context =>
{
context.Response.StatusCode = 500;
- context.Response.Headers[HeaderNames.CacheControl] = "no-cache";
+ context.Response.Headers[HeaderNames.CacheControl] = "no-cache,no-store";
+ context.Response.Headers[HeaderNames.Pragma] = "no-cache";
return errorPage.ExecuteAsync(context);
};
}
diff --git a/src/Middleware/Diagnostics.EntityFrameworkCore/src/MigrationsEndPointMiddleware.cs b/src/Middleware/Diagnostics.EntityFrameworkCore/src/MigrationsEndPointMiddleware.cs
index 0a37bf7f3e99..96606122fa63 100644
--- a/src/Middleware/Diagnostics.EntityFrameworkCore/src/MigrationsEndPointMiddleware.cs
+++ b/src/Middleware/Diagnostics.EntityFrameworkCore/src/MigrationsEndPointMiddleware.cs
@@ -28,8 +28,8 @@ public class MigrationsEndPointMiddleware
/// The to write messages to.
/// The options to control the behavior of the middleware.
public MigrationsEndPointMiddleware(
- RequestDelegate next,
- ILogger logger,
+ RequestDelegate next,
+ ILogger logger,
IOptions options)
{
if (next == null)
@@ -80,7 +80,7 @@ public virtual async Task Invoke(HttpContext context)
context.Response.StatusCode = (int)HttpStatusCode.NoContent;
context.Response.Headers.Add("Pragma", new[] { "no-cache" });
- context.Response.Headers.Add("Cache-Control", new[] { "no-cache" });
+ context.Response.Headers.Add("Cache-Control", new[] { "no-cache,no-store" });
_logger.MigrationsApplied(db.GetType().FullName);
}
@@ -147,7 +147,7 @@ private static async Task WriteErrorToResponse(HttpResponse response, string err
{
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.Headers.Add("Pragma", new[] { "no-cache" });
- response.Headers.Add("Cache-Control", new[] { "no-cache" });
+ response.Headers.Add("Cache-Control", new[] { "no-cache,no-store" });
response.ContentType = "text/plain";
// Padding to >512 to ensure IE doesn't hide the message
diff --git a/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerMiddleware.cs b/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerMiddleware.cs
index 5d280b5f43a8..65564cbd5926 100644
--- a/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerMiddleware.cs
+++ b/src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerMiddleware.cs
@@ -153,7 +153,7 @@ private static void ClearHttpContext(HttpContext context)
private static Task ClearCacheHeaders(object state)
{
var headers = ((HttpResponse)state).Headers;
- headers[HeaderNames.CacheControl] = "no-cache";
+ headers[HeaderNames.CacheControl] = "no-cache,no-store";
headers[HeaderNames.Pragma] = "no-cache";
headers[HeaderNames.Expires] = "-1";
headers.Remove(HeaderNames.ETag);
diff --git a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs
index b63eaa4a9892..d24965b760d6 100644
--- a/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs
+++ b/src/Middleware/Diagnostics/test/UnitTests/ExceptionHandlerTest.cs
@@ -164,9 +164,8 @@ public async Task ClearsResponseBuffer_BeforeRequestIsReexecuted()
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.Equal(expectedResponseBody, await response.Content.ReadAsStringAsync());
IEnumerable values;
- Assert.True(response.Headers.TryGetValues("Cache-Control", out values));
- Assert.Single(values);
- Assert.Equal("no-cache", values.First());
+ Assert.True(response.Headers.CacheControl.NoCache);
+ Assert.True(response.Headers.CacheControl.NoStore);
Assert.True(response.Headers.TryGetValues("Pragma", out values));
Assert.Single(values);
Assert.Equal("no-cache", values.First());
@@ -214,9 +213,8 @@ public async Task ClearsCacheHeaders_SetByReexecutionPathHandlers()
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.Equal(expectedResponseBody, await response.Content.ReadAsStringAsync());
IEnumerable values;
- Assert.True(response.Headers.TryGetValues("Cache-Control", out values));
- Assert.Single(values);
- Assert.Equal("no-cache", values.First());
+ Assert.True(response.Headers.CacheControl.NoCache);
+ Assert.True(response.Headers.CacheControl.NoStore);
Assert.True(response.Headers.TryGetValues("Pragma", out values));
Assert.Single(values);
Assert.Equal("no-cache", values.First());
diff --git a/src/Middleware/Session/src/SessionMiddleware.cs b/src/Middleware/Session/src/SessionMiddleware.cs
index fd7fd6532407..5810de51bca0 100644
--- a/src/Middleware/Session/src/SessionMiddleware.cs
+++ b/src/Middleware/Session/src/SessionMiddleware.cs
@@ -161,7 +161,7 @@ private void SetCookie()
response.Cookies.Append(_options.Cookie.Name, _cookieValue, cookieOptions);
var responseHeaders = response.Headers;
- responseHeaders[HeaderNames.CacheControl] = "no-cache";
+ responseHeaders[HeaderNames.CacheControl] = "no-cache,no-store";
responseHeaders[HeaderNames.Pragma] = "no-cache";
responseHeaders[HeaderNames.Expires] = "-1";
}
diff --git a/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs b/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs
index 25e0e3d0398b..5a0d63d95d13 100644
--- a/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs
+++ b/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs
@@ -17,6 +17,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
public class CookieAuthenticationHandler : SignInAuthenticationHandler
{
private const string HeaderValueNoCache = "no-cache";
+ private const string HeaderValueNoCacheNoStore = "no-cache,no-store";
private const string HeaderValueEpocDate = "Thu, 01 Jan 1970 00:00:00 GMT";
private const string SessionIdClaim = "Microsoft.AspNetCore.Authentication.Cookies-SessionId";
@@ -374,7 +375,7 @@ protected async override Task HandleSignOutAsync(AuthenticationProperties proper
private async Task ApplyHeaders(bool shouldRedirectToReturnUrl, AuthenticationProperties properties)
{
- Response.Headers[HeaderNames.CacheControl] = HeaderValueNoCache;
+ Response.Headers[HeaderNames.CacheControl] = HeaderValueNoCacheNoStore;
Response.Headers[HeaderNames.Pragma] = HeaderValueNoCache;
Response.Headers[HeaderNames.Expires] = HeaderValueEpocDate;
diff --git a/src/Security/Authentication/test/CookieTests.cs b/src/Security/Authentication/test/CookieTests.cs
index 44775187129f..e1a3840e193e 100644
--- a/src/Security/Authentication/test/CookieTests.cs
+++ b/src/Security/Authentication/test/CookieTests.cs
@@ -138,6 +138,9 @@ public async Task SignInCausesDefaultCookieToBeCreated()
Assert.DoesNotContain("; expires=", setCookie);
Assert.DoesNotContain("; domain=", setCookie);
Assert.DoesNotContain("; secure", setCookie);
+ Assert.True(transaction.Response.Headers.CacheControl.NoCache);
+ Assert.True(transaction.Response.Headers.CacheControl.NoStore);
+ Assert.Equal("no-cache", transaction.Response.Headers.Pragma.ToString());
}
[Fact]
diff --git a/src/SignalR/common/Http.Connections/src/Internal/Transports/ServerSentEventsServerTransport.cs b/src/SignalR/common/Http.Connections/src/Internal/Transports/ServerSentEventsServerTransport.cs
index 3d5e1f6f4bd5..450299bda302 100644
--- a/src/SignalR/common/Http.Connections/src/Internal/Transports/ServerSentEventsServerTransport.cs
+++ b/src/SignalR/common/Http.Connections/src/Internal/Transports/ServerSentEventsServerTransport.cs
@@ -35,7 +35,8 @@ public ServerSentEventsServerTransport(PipeReader application, string connection
public async Task ProcessRequestAsync(HttpContext context, CancellationToken token)
{
context.Response.ContentType = "text/event-stream";
- context.Response.Headers[HeaderNames.CacheControl] = "no-cache";
+ context.Response.Headers[HeaderNames.CacheControl] = "no-cache,no-store";
+ context.Response.Headers[HeaderNames.Pragma] = "no-cache";
// Make sure we disable all response buffering for SSE
var bufferingFeature = context.Features.Get();
diff --git a/src/SignalR/common/Http.Connections/test/ServerSentEventsTests.cs b/src/SignalR/common/Http.Connections/test/ServerSentEventsTests.cs
index 4d53761699c1..85d929e8b9c6 100644
--- a/src/SignalR/common/Http.Connections/test/ServerSentEventsTests.cs
+++ b/src/SignalR/common/Http.Connections/test/ServerSentEventsTests.cs
@@ -31,7 +31,8 @@ public async Task SSESetsContentType()
await sse.ProcessRequestAsync(context, context.RequestAborted);
Assert.Equal("text/event-stream", context.Response.ContentType);
- Assert.Equal("no-cache", context.Response.Headers["Cache-Control"]);
+ Assert.Equal("no-cache,no-store", context.Response.Headers["Cache-Control"]);
+ Assert.Equal("no-cache", context.Response.Headers["Pragma"]);
}
}