diff --git a/src/protagonist/Orchestrator.Tests/Integration/AuthHandlingTests.cs b/src/protagonist/Orchestrator.Tests/Integration/AuthHandlingTests.cs index aa7818981..fce9c556f 100644 --- a/src/protagonist/Orchestrator.Tests/Integration/AuthHandlingTests.cs +++ b/src/protagonist/Orchestrator.Tests/Integration/AuthHandlingTests.cs @@ -54,6 +54,7 @@ public async Task Get_Clickthrough_UnknownCustomer_Returns400() // Assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -67,6 +68,7 @@ public async Task Get_UnknownRole_Returns404() // Assert response.StatusCode.Should().Be(HttpStatusCode.NotFound); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -110,6 +112,7 @@ public async Task Get_Token_Returns401_WithErrorJson_IfNoCookie_AndMessageIdNotP // Assert response.StatusCode.Should().Be(HttpStatusCode.Unauthorized); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); var responseBody = JObject.Parse(await response.Content.ReadAsStringAsync()); responseBody["error"].Value().Should().Be("missingCredentials"); @@ -129,6 +132,7 @@ public async Task Get_Token_Returns403_WithErrorJson_IfCookieDoesNotContainId_An // Assert response.StatusCode.Should().Be(HttpStatusCode.Forbidden); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); var responseBody = JObject.Parse(await response.Content.ReadAsStringAsync()); responseBody["error"].Value().Should().Be("invalidCredentials"); @@ -148,6 +152,7 @@ public async Task Get_Token_Returns403_WithErrorJson_IfCookieDoesNotContainKnown // Assert response.StatusCode.Should().Be(HttpStatusCode.Forbidden); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); var responseBody = JObject.Parse(await response.Content.ReadAsStringAsync()); responseBody["error"].Value().Should().Be("invalidCredentials"); @@ -169,6 +174,7 @@ public async Task Get_Token_Returns403_WithErrorJson_IfCookieContainsId_ForDiffe // Assert response.StatusCode.Should().Be(HttpStatusCode.Forbidden); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); var responseBody = JObject.Parse(await response.Content.ReadAsStringAsync()); responseBody["error"].Value().Should().Be("invalidCredentials"); @@ -190,6 +196,7 @@ public async Task Get_Token_Returns403_WithErrorJson_IfCookieContainsExpiredId_A // Assert response.StatusCode.Should().Be(HttpStatusCode.Forbidden); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); var responseBody = JObject.Parse(await response.Content.ReadAsStringAsync()); responseBody["error"].Value().Should().Be("invalidCredentials"); @@ -215,6 +222,7 @@ public async Task Get_Token_Returns200_WithAccessToken_IfSuccess_AndMessageIdNot var responseBody = JObject.Parse(await response.Content.ReadAsStringAsync()); responseBody["accessToken"].Value().Should().Be(token.Entity.BearerToken); responseBody["expiresIn"].Value().Should().Be(token.Entity.Ttl); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } #endregion @@ -234,6 +242,7 @@ public async Task Get_Token_ReturnsView_WithErrorJson_IfNoCookie() var responseBody = await ParseHtmlTokenReponse(response); responseBody["error"].Value().Should().Be("missingCredentials"); responseBody["description"].Value().Should().Be("Required cookie missing"); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -253,6 +262,7 @@ public async Task Get_Token_ReturnsView_WithErrorJson_IfCookieDoesNotContainId() var responseBody = await ParseHtmlTokenReponse(response); responseBody["error"].Value().Should().Be("invalidCredentials"); responseBody["description"].Value().Should().Be("Id not found in cookie"); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -272,6 +282,7 @@ public async Task Get_Token_ReturnsView_WithErrorJson_IfCookieDoesNotContainKnow var responseBody = await ParseHtmlTokenReponse(response); responseBody["error"].Value().Should().Be("invalidCredentials"); responseBody["description"].Value().Should().Be("Credentials provided unknown or expired"); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -293,6 +304,7 @@ public async Task Get_Token_ReturnsView_WithErrorJson_IfCookieContainsId_ForDiff var responseBody = await ParseHtmlTokenReponse(response); responseBody["error"].Value().Should().Be("invalidCredentials"); responseBody["description"].Value().Should().Be("Credentials provided unknown or expired"); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -314,6 +326,7 @@ public async Task Get_Token_ReturnsView_WithErrorJson_IfCookieContainsExpiredId( var responseBody = await ParseHtmlTokenReponse(response); responseBody["error"].Value().Should().Be("invalidCredentials"); responseBody["description"].Value().Should().Be("Credentials provided unknown or expired"); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } [Fact] @@ -336,6 +349,7 @@ public async Task Get_Token_ReturnsView_WithAccessToken_IfSuccess() responseBody["accessToken"].Value().Should().Be(token.Entity.BearerToken); responseBody["expiresIn"].Value().Should().Be(token.Entity.Ttl); responseBody["messageId"].Value().Should().Be("123"); + response.Headers.CacheControl!.NoStore.Should().BeTrue(); } #endregion @@ -369,6 +383,7 @@ public async Task ProbeService_404_IfAssetNotFound() // Assert result.StatusCode.Should().Be(HttpStatusCode.NotFound); + result.Headers.CacheControl.Should().BeNull(); result.Content.Headers.ContentType.MediaType .Should().Be("application/problem+json", "this isn't an AuthProbeResult2"); } diff --git a/src/protagonist/Orchestrator/Features/Auth/AuthController.cs b/src/protagonist/Orchestrator/Features/Auth/AuthController.cs index bba81c5b7..42f7f1d7c 100644 --- a/src/protagonist/Orchestrator/Features/Auth/AuthController.cs +++ b/src/protagonist/Orchestrator/Features/Auth/AuthController.cs @@ -29,6 +29,7 @@ public AuthController(IMediator mediator, IOptions cacheSettings, /// Handle clickthrough auth request - create a new auth cookie and return View for user to close /// [Route("{customer}/clickthrough")] + [ResponseCache(NoStore = true)] [HttpGet] public async Task Clickthrough(int customer) { @@ -47,6 +48,7 @@ public async Task Clickthrough(int customer) /// See https://iiif.io/api/auth/1.0/#access-token-service /// [Route("{customer}/token")] + [ResponseCache(NoStore = true)] [HttpGet] public async Task Token(int customer, string? messageId, string? origin) { @@ -87,6 +89,7 @@ public async Task Token(int customer, string? messageId, string? /// Name of authService to initiate. /// Redirect to downstream role-provider login service [Route("{customer}/{authService}")] + [ResponseCache(NoStore = true)] [HttpGet] public async Task InitiateAuthService(int customer, string authService) { @@ -104,6 +107,7 @@ public async Task InitiateAuthService(int customer, string authSe /// Name of authService. /// Role-provider token [Route("{customer}/{authService}")] + [ResponseCache(NoStore = true)] [HttpGet] public async Task RoleProviderToken(int customer, string authService, [RequiredFromQuery] string token) @@ -125,6 +129,7 @@ public async Task RoleProviderToken(int customer, string authServ /// Name of authService. /// [Route("{customer}/{authService}/logout")] + [ResponseCache(NoStore = true)] [HttpGet] public async Task Logout(int customer, string authService) {