Description
Some of the legacy back ends behind our gateway have their own CORS filters.
On non-OPTIONS requests, they return their own Access-Control-Allow-Origin and Access-Control-Allow-Credentials response headers. With Finchley train, the gateway's CORS processor would not duplicate these response headers. After upgrade to Greenwich BUILD-SNAPSHOT and Spring Boot 2.1.1.Release, these response headers are in two copies each, rightfully upsetting the consumer (Angular based) apps:
Access to XMLHttpRequest at 'https://XXX' from origin 'https://YYY' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'https://YYY, https://YYY', but only one is allowed.
I will dedup those with a global post filter for now, but still thought to file this issue as the behavior changed and perhaps can be fixed at the source. Here is an integration test snippet I have that succeeds with Finchley train but fails with Greenwich:
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("integration")
public class CorsHeadersUniquenessTest {
@LocalServerPort
private int port;
private WebTestClient webClient;
private String baseUri;
private static ClientAndServer mockRest;
@BeforeClass
public static void startServer() {
mockRest = ClientAndServer.startClientAndServer(38492);
mockRest.when(request().withMethod("GET").withPath("/v2/version"))
.respond(response().withStatusCode(200)
.withHeader("Access-Control-Allow-Credentials", "true")
.withHeader("Access-Control-Allow-Origin", "http://wat.com"));
}
@AfterClass
public static void stopServer() {
mockRest.stop();
}
@Before
public void setup() {
baseUri = "http://localhost:" + port;
this.webClient = WebTestClient.bindToServer().responseTimeout(Duration.ofSeconds(3)).baseUrl(baseUri).build();
}
/*
Some of the backends implement their own CORS filters, returning the response headers below.
As we were upgrading SCG from Finchley to Greenwich, we got those response headers doubled.
This test is here to capture the error.
Note that OPTIONS (a.k.a. preflight) requests are fine - they never reach backends.
All the other methods do.
*/
@Test
public void testCors() {
webClient.get().uri("/v2/version")
.header("Access-Control-Request-Method", "GET")
.header("Origin", "http://wat.com")
.exchange()
.expectStatus().isOk()
.expectHeader().valueEquals("Access-Control-Allow-Origin", "http://wat.com")
.expectHeader().valueEquals("Access-Control-Allow-Credentials", "true")
;
}
}