Skip to content

Commit dd96c87

Browse files
committed
Improve docs on forwarded headers
Issue: SPR-16660
1 parent a546cf0 commit dd96c87

File tree

11 files changed

+115
-22
lines changed

11 files changed

+115
-22
lines changed

spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -81,6 +81,13 @@
8181
* <p>A matched origin is listed in the {@code Access-Control-Allow-Origin}
8282
* response header of preflight actual CORS requests.
8383
* <p>By default all origins are allowed.
84+
* <p><strong>Note:</strong> CORS checks use values from "Forwarded"
85+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
86+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
87+
* if present, in order to reflect the client-originated address.
88+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
89+
* central place whether to extract and use, or to discard such headers.
90+
* See the Spring Framework reference for more on this filter.
8491
* @see #value
8592
*/
8693
@AliasFor("value")

spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -145,6 +145,13 @@ else if (this.allowedOrigins == DEFAULT_PERMIT_ALL) {
145145
* <p>The special value {@code "*"} allows all methods.
146146
* <p>If not set, only {@code "GET"} and {@code "HEAD"} are allowed.
147147
* <p>By default this is not set.
148+
* <p><strong>Note:</strong> CORS checks use values from "Forwarded"
149+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
150+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
151+
* if present, in order to reflect the client-originated address.
152+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
153+
* central place whether to extract and use, or to discard such headers.
154+
* See the Spring Framework reference for more on this filter.
148155
*/
149156
public void setAllowedMethods(@Nullable List<String> allowedMethods) {
150157
this.allowedMethods = (allowedMethods != null ? new ArrayList<>(allowedMethods) : null);

spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ public static boolean isPreFlightRequest(ServerHttpRequest request) {
5454
* @code X-Forwarded-Port} headers.
5555
* @return {@code true} if the request is a same-origin one, {@code false} in case
5656
* of a cross-origin request
57+
* <p><strong>Note:</strong> this method uses values from "Forwarded"
58+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
59+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
60+
* if present, in order to reflect the client-originated address.
61+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
62+
* central place whether to extract and use, or to discard such headers.
63+
* See the Spring Framework reference for more on this filter.
5764
*/
5865
public static boolean isSameOrigin(ServerHttpRequest request) {
5966
String origin = request.getHeaders().getOrigin();

spring-web/src/main/java/org/springframework/web/util/WebUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,13 @@ public static MultiValueMap<String, String> parseMatrixVariables(String matrixVa
677677
* Check the given request origin against a list of allowed origins.
678678
* A list containing "*" means that all origins are allowed.
679679
* An empty list means only same origin is allowed.
680+
* <p><strong>Note:</strong> this method may use values from "Forwarded"
681+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
682+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
683+
* if present, in order to reflect the client-originated address.
684+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
685+
* central place whether to extract and use, or to discard such headers.
686+
* See the Spring Framework reference for more on this filter.
680687
* @return {@code true} if the request origin is valid, {@code false} otherwise
681688
* @since 4.1.5
682689
* @see <a href="https://tools.ietf.org/html/rfc6454">RFC 6454: The Web Origin Concept</a>
@@ -701,6 +708,13 @@ else if (CollectionUtils.isEmpty(allowedOrigins)) {
701708
* Check if the request is a same-origin one, based on {@code Origin}, {@code Host},
702709
* {@code Forwarded}, {@code X-Forwarded-Proto}, {@code X-Forwarded-Host} and
703710
* @code X-Forwarded-Port} headers.
711+
* <p><strong>Note:</strong> this method uses values from "Forwarded"
712+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
713+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
714+
* if present, in order to reflect the client-originated address.
715+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
716+
* central place whether to extract and use, or to discard such headers.
717+
* See the Spring Framework reference for more on this filter.
704718
* @return {@code true} if the request is a same-origin one, {@code false} in case
705719
* of cross-origin request
706720
* @since 4.2

spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -49,6 +49,13 @@ public CorsRegistration(String pathPattern) {
4949
* <p>A matched origin is listed in the {@code Access-Control-Allow-Origin}
5050
* response header of preflight actual CORS requests.
5151
* <p>By default all origins are allowed.
52+
* <p><strong>Note:</strong> CORS checks use values from "Forwarded"
53+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
54+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
55+
* if present, in order to reflect the client-originated address.
56+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
57+
* central place whether to extract and use, or to discard such headers.
58+
* See the Spring Framework reference for more on this filter.
5259
*/
5360
public CorsRegistration allowedOrigins(String... origins) {
5461
this.config.setAllowedOrigins(new ArrayList<>(Arrays.asList(origins)));

spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,6 +51,13 @@ public CorsRegistration(String pathPattern) {
5151
* <p>A matched origin is listed in the {@code Access-Control-Allow-Origin}
5252
* response header of preflight actual CORS requests.
5353
* <p>By default, all origins are allowed.
54+
* <p><strong>Note:</strong> CORS checks use values from "Forwarded"
55+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
56+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
57+
* if present, in order to reflect the client-originated address.
58+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
59+
* central place whether to extract and use, or to discard such headers.
60+
* See the Spring Framework reference for more on this filter.
5461
*/
5562
public CorsRegistration allowedOrigins(String... origins) {
5663
this.config.setAllowedOrigins(Arrays.asList(origins));

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -83,14 +83,13 @@
8383
* {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}.
8484
* </ul>
8585
*
86-
* <p><strong>Note:</strong> This class extracts and uses values from the headers
87-
* "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
88-
* or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if
89-
* "Forwarded" is not found, in order to reflect the client-originated protocol
90-
* and address. As an alternative consider using the
91-
* {@link org.springframework.web.filter.ForwardedHeaderFilter} to have such
92-
* headers extracted once and removed, or removed only (without being used).
93-
* See the reference for further information including security considerations.
86+
* <p><strong>Note:</strong> This class uses values from "Forwarded"
87+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
88+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
89+
* if present, in order to reflect the client-originated protocol and address.
90+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
91+
* central place whether to extract and use, or to discard such headers.
92+
* See the Spring Framework reference for more on this filter.
9493
*
9594
* @author Oliver Gierke
9695
* @author Rossen Stoyanchev

spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@
3636
* UriComponentsBuilder with additional static factory methods to create links
3737
* based on the current HttpServletRequest.
3838
*
39-
* <p><strong>Note:</strong> This class extracts and uses values from the headers
40-
* "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
41-
* or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if
42-
* "Forwarded" is not found, in order to reflect the client-originated protocol
43-
* and address. As an alternative consider using the
44-
* {@link org.springframework.web.filter.ForwardedHeaderFilter} to have such
45-
* headers extracted once and removed, or removed only (without being used).
46-
* See the reference for further information including security considerations.
39+
* <p><strong>Note:</strong> This class uses values from "Forwarded"
40+
* (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
41+
* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
42+
* if present, in order to reflect the client-originated protocol and address.
43+
* Consider using the {@code ForwardedHeaderFilter} in order to choose from a
44+
* central place whether to extract and use, or to discard such headers.
45+
* See the Spring Framework reference for more on this filter.
4746
*
4847
* @author Rossen Stoyanchev
4948
* @since 3.1

spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,12 @@
13311331
<xsd:documentation><![CDATA[
13321332
Comma-separated list of origins to allow, e.g. "http://domain1.com, http://domain2.com".
13331333
The special value "*" allows all domains (default).
1334+
1335+
Note that CORS checks use values from "Forwarded" (RFC 7239), "X-Forwarded-Host",
1336+
"X-Forwarded-Port", and "X-Forwarded-Proto" headers, if present, in order to reflect
1337+
the client-originated address. Consider using the ForwardedHeaderFilter in order to
1338+
choose from a central place whether to extract and use such headers, or whether to
1339+
discard them. See the Spring Framework reference for more on this filter.
13341340
]]></xsd:documentation>
13351341
</xsd:annotation>
13361342
</xsd:attribute>

src/docs/asciidoc/web/webflux.adoc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,44 @@ views through the <<webflux-config-view-resolvers,WebFlux Config>>. Default view
854854
always selected and used if they match the requested media type.
855855

856856

857+
[[webflux-filters]]
858+
== Filters
859+
[.small]#<<web.adoc#filters,Same in Spring MVC>>#
860+
861+
As part of the <<webflux-web-handler-api>>, the `spring-web` module provides a number of
862+
`WebFilter` implementations.
863+
864+
865+
866+
[[webflux-filters-forwarded-headers]]
867+
=== Forwarded Headers
868+
[.small]#<<web.adoc#filters-forwarded-headers,Same in Spring MVC>>#
869+
870+
As a request goes through proxies such as load balancers the host, port, and
871+
scheme may change presenting a challenge for applications that need to create links
872+
to resources since the links should reflect the host, port, and scheme of the
873+
original request as seen from a client perspective.
874+
875+
https://tools.ietf.org/html/rfc7239[RFC 7239] defines the "Forwarded" HTTP header
876+
for proxies to use to provide information about the original request. There are also
877+
other non-standard headers in use such as "X-Forwarded-Host", "X-Forwarded-Port",
878+
and "X-Forwarded-Proto".
879+
880+
`ForwardedHeaderFilter` detects, extracts, and uses information from the "Forwarded"
881+
header, or from "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto".
882+
It wraps the request in order to overlay its host, port, and scheme and also "hides"
883+
the forwarded headers for subsequent processing.
884+
885+
Note that there are security considerations when using forwarded headers as explained
886+
in Section 8 of RFC 7239. At the application level it is difficult to determine whether
887+
forwarded headers can be trusted or not. This is why the network upstream should be
888+
configured correctly to filter out untrusted forwarded headers from the outside.
889+
890+
Applications that don't have a proxy and don't need to use forwarded headers can
891+
configure the `ForwardedHeaderFilter` to remove and ignore such headers.
892+
893+
894+
857895

858896

859897
[[webflux-controller]]

0 commit comments

Comments
 (0)