feat(security): trust X-Forwarded-Proto behind reverse proxy
Adds server.forward-headers-strategy: native so that Jetty honours
X-Forwarded-{Proto,For,Host} from Caddy. Without this, getScheme(),
redirect URLs, and Spring Session "Secure" cookies reflect the
internal http hop instead of the original https client request.
Refs #497.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,12 @@ spring:
|
|||||||
starttls:
|
starttls:
|
||||||
enable: true
|
enable: true
|
||||||
|
|
||||||
|
server:
|
||||||
|
# Behind Caddy/reverse proxy: trust X-Forwarded-{Proto,For,Host} so that
|
||||||
|
# request.getScheme(), redirect URLs, and Spring Session "Secure" cookies
|
||||||
|
# reflect the original https client request, not the http hop from Caddy.
|
||||||
|
forward-headers-strategy: native
|
||||||
|
|
||||||
management:
|
management:
|
||||||
health:
|
health:
|
||||||
mail:
|
mail:
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.raddatz.familienarchiv.config;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.raddatz.familienarchiv.PostgresContainerConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
|
import software.amazon.awssdk.services.s3.S3Client;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
@Import(PostgresContainerConfig.class)
|
||||||
|
class ForwardHeadersConfigurationTest {
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
|
S3Client s3Client;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Value("${server.forward-headers-strategy:}")
|
||||||
|
String forwardHeadersStrategy;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void forward_headers_strategy_is_native_for_reverse_proxy_deployment() {
|
||||||
|
// Caddy terminates TLS and forwards X-Forwarded-Proto: https.
|
||||||
|
// Spring must trust those headers so that AppUser-facing redirect URLs,
|
||||||
|
// Spring Session cookies (Secure flag), and HttpServletRequest.getScheme()
|
||||||
|
// reflect the original client-facing scheme rather than the internal http hop.
|
||||||
|
assertThat(forwardHeadersStrategy)
|
||||||
|
.as("server.forward-headers-strategy must be 'native' so Jetty honours X-Forwarded-Proto behind Caddy")
|
||||||
|
.isEqualTo("native");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user