Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preserve host header + set forward-headers-strategy FRAMEWORK #109

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* {@link java.net.UnknownHostException} and {@link java.net.ConnectException}
* to {@link HttpStatus#SERVICE_UNAVAILABLE}
*/
class CustomErrorAttributes extends DefaultErrorAttributes {
public class CustomErrorAttributes extends DefaultErrorAttributes {

@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Expand Down
2 changes: 2 additions & 0 deletions gateway/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ server:
ssl:
enabled: false
#TODO: configure SSL with a self-signed certificate
forward-headers-strategy: FRAMEWORK

spring:
config:
Expand Down Expand Up @@ -52,6 +53,7 @@ spring:
- RemoveSecurityHeaders
# AddSecHeaders appends sec-* headers to proxied requests based on the currently authenticated user
- AddSecHeaders
- PreserveHostHeader
- ApplicationError
global-filter:
websocket-routing:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import org.georchestra.gateway.autoconfigure.app.CustomErrorAttributes;
import org.georchestra.gateway.autoconfigure.app.ErrorCustomizerAutoConfiguration;
import org.georchestra.gateway.security.ldap.extended.GeorchestraUserNamePasswordAuthenticationToken;
import org.junit.jupiter.api.Test;
Expand All @@ -39,6 +40,7 @@
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
Expand All @@ -59,6 +61,8 @@ class GeorchestraGatewayApplicationTests {
private @Autowired GeorchestraGatewayApplication application;
private @Autowired WebTestClient testClient;

private @Autowired ApplicationContext context;

@Test
void contextLoadsFromDatadir() {
assertEquals("src/test/resources/test-datadir", env.getProperty("georchestra.datadir"));
Expand Down Expand Up @@ -109,12 +113,13 @@ void makeSureWhoamiDoesNotProvideAnySensitiveInfo() {
void errorCustomizerReturnsServiceUnavailableInsteadOfServerError() {
Map<String, Route> routesById = routeLocator.getRoutes()
.collect(Collectors.toMap(Route::getId, Function.identity())).block();

assertThat(context.getBean(CustomErrorAttributes.class)).isNotNull();
Route testRoute = routesById.get("unknownHostRoute");
assertNotNull(testRoute);
assertThat(testRoute.getUri()).isEqualTo(URI.create("http://not.a.valid.host:80"));

testClient.get().uri("/path/to/unavailable/service").exchange().expectStatus()
.isEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
testClient.get().uri("/path/to/unavailable/service")//
.header("Host", "localhost")//
.exchange().expectStatus().isEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ protected void doStart() {
assertNotNull(context.getBean(JsonPayloadHeadersContributor.class));

testClient.get().uri("/echo/")//
.header("Host", "localhost")//
.header("Authorization", "Basic dGVzdGFkbWluOnRlc3RhZG1pbg==") // testadmin:testadmin
.exchange()//
.expectStatus()//
Expand All @@ -81,6 +82,7 @@ protected void doStart() {
gatewayConfig.getDefaultHeaders().setJsonOrganization(Optional.of(false));

testClient.get().uri("/echo/")//
.header("Host", "localhost")//
.header("Authorization", "Basic dGVzdGFkbWluOnRlc3RhZG1pbg==") // testadmin:testadmin
.exchange()//
.expectStatus()//
Expand All @@ -96,6 +98,7 @@ protected void doStart() {
gatewayConfig.getDefaultHeaders().setJsonOrganization(Optional.of(true));

testClient.get().uri("/echo/")//
.header("Host", "localhost")//
.header("Authorization", "Basic dGVzdGFkbWluOnRlc3RhZG1pbg==") // testadmin:testadmin
.exchange()//
.expectStatus()//
Expand All @@ -107,6 +110,7 @@ protected void doStart() {

public @Test void testSecOrgnamePresent() {
testClient.get().uri("/echo/")//
.header("Host", "localhost")//
.header("Authorization", "Basic dGVzdGFkbWluOnRlc3RhZG1pbg==") // testadmin:testadmin
.exchange()//
.expectStatus()//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@

package org.georchestra.gateway.security.accessrules;

import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.noContent;
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;

import java.net.URI;

import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import lombok.extern.slf4j.Slf4j;
import org.georchestra.gateway.app.GeorchestraGatewayApplication;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
Expand All @@ -40,11 +36,9 @@
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.test.web.reactive.server.WebTestClient;

import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import java.net.URI;

import lombok.extern.slf4j.Slf4j;
import static com.github.tomakehurst.wiremock.client.WireMock.*;

/**
* Integration tests for {@link AccessRulesCustomizer} for the access rules in
Expand Down Expand Up @@ -133,8 +127,12 @@ private static void mockServiceTarget(DynamicPropertyRegistry registry, String s
.withHeader("sec-proxy", equalTo("true"))//
.willReturn(ok()));

testClient.get().uri("/header").exchange().expectStatus().isOk();
testClient.get().uri("/header/img/logo.png").exchange().expectStatus().isOk();
testClient.get().uri("/header")//
.header("Host", "localhost")//
.exchange().expectStatus().isOk();
testClient.get().uri("/header/img/logo.png")//
.header("Host", "localhost")//
.exchange().expectStatus().isOk();
}

/**
Expand Down Expand Up @@ -172,10 +170,12 @@ private static void mockServiceTarget(DynamicPropertyRegistry registry, String s
mockService.stubFor(get(urlMatching("/import(/.*)?")).willReturn(ok()));

testClient.get().uri("/import")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();

testClient.get().uri("/import/any/thing")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();
}
Expand Down Expand Up @@ -216,10 +216,12 @@ private static void mockServiceTarget(DynamicPropertyRegistry registry, String s
mockService.stubFor(get(urlMatching("/analytics(/.*)?")).willReturn(ok()));

testClient.get().uri("/analytics")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();

testClient.get().uri("/analytics/any/thing")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();
}
Expand Down Expand Up @@ -264,10 +266,12 @@ void testGlobalAccessRule() {
mockService.stubFor(get(urlMatching("/mapstore(/.*)?")).willReturn(ok()));

testClient.get().uri("/mapstore")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();

testClient.get().uri("/mapstore/any/thing")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();
}
Expand All @@ -281,6 +285,7 @@ void testQueryParamAuthentication_forbidden_when_anonymous() {
.expectStatus().is3xxRedirection();

testClient.get().uri("/header")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();
}
Expand All @@ -291,10 +296,12 @@ void testQueryParamAuthentication_authorized_if_logged_in() {
mockService.stubFor(get(urlMatching("/header(.*)?")).willReturn(ok()));

testClient.get().uri("/header?login")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();

testClient.get().uri("/header")//
.header("Host", "localhost")//
.exchange()//
.expectStatus().isOk();
}
Expand Down
Loading