diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java index 76d49fb894..5efafcb77e 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,6 +81,13 @@ public @interface CrossOrigin { *

A matched origin is listed in the {@code Access-Control-Allow-Origin} * response header of preflight actual CORS requests. *

By default all origins are allowed. + *

Note: CORS checks use values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. * @see #value */ @AliasFor("value") diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java index 6b39369d67..5478bb6656 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -145,6 +145,13 @@ public class CorsConfiguration { *

The special value {@code "*"} allows all methods. *

If not set, only {@code "GET"} and {@code "HEAD"} are allowed. *

By default this is not set. + *

Note: CORS checks use values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. */ public void setAllowedMethods(@Nullable List allowedMethods) { this.allowedMethods = (allowedMethods != null ? new ArrayList<>(allowedMethods) : null); diff --git a/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java b/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java index 073409a0d6..23380447ed 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java +++ b/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java @@ -54,6 +54,13 @@ public abstract class CorsUtils { * @code X-Forwarded-Port} headers. * @return {@code true} if the request is a same-origin one, {@code false} in case * of a cross-origin request + *

Note: this method uses values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. */ public static boolean isSameOrigin(ServerHttpRequest request) { String origin = request.getHeaders().getOrigin(); diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java index 3a390245fa..6af42f4546 100644 --- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java @@ -677,6 +677,13 @@ public abstract class WebUtils { * Check the given request origin against a list of allowed origins. * A list containing "*" means that all origins are allowed. * An empty list means only same origin is allowed. + *

Note: this method may use values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. * @return {@code true} if the request origin is valid, {@code false} otherwise * @since 4.1.5 * @see RFC 6454: The Web Origin Concept @@ -701,6 +708,13 @@ public abstract class WebUtils { * Check if the request is a same-origin one, based on {@code Origin}, {@code Host}, * {@code Forwarded}, {@code X-Forwarded-Proto}, {@code X-Forwarded-Host} and * @code X-Forwarded-Port} headers. + *

Note: this method uses values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. * @return {@code true} if the request is a same-origin one, {@code false} in case * of cross-origin request * @since 4.2 diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistration.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistration.java index e70119c7fd..0c4d6cc94c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistration.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,13 @@ public class CorsRegistration { *

A matched origin is listed in the {@code Access-Control-Allow-Origin} * response header of preflight actual CORS requests. *

By default all origins are allowed. + *

Note: CORS checks use values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. */ public CorsRegistration allowedOrigins(String... origins) { this.config.setAllowedOrigins(new ArrayList<>(Arrays.asList(origins))); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistration.java index db1b192e38..429836ef2a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +51,13 @@ public class CorsRegistration { *

A matched origin is listed in the {@code Access-Control-Allow-Origin} * response header of preflight actual CORS requests. *

By default, all origins are allowed. + *

Note: CORS checks use values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. */ public CorsRegistration allowedOrigins(String... origins) { this.config.setAllowedOrigins(Arrays.asList(origins)); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index 6ab89eccbb..f217e911b8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,14 +83,13 @@ import org.springframework.web.util.UriComponentsBuilder; * {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}. * * - *

Note: This class extracts and uses values from the headers - * "Forwarded" (RFC 7239), - * or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if - * "Forwarded" is not found, in order to reflect the client-originated protocol - * and address. As an alternative consider using the - * {@link org.springframework.web.filter.ForwardedHeaderFilter} to have such - * headers extracted once and removed, or removed only (without being used). - * See the reference for further information including security considerations. + *

Note: This class uses values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated protocol and address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. * * @author Oliver Gierke * @author Rossen Stoyanchev diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java index 17ac0343a9..8f50db6319 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java @@ -36,14 +36,13 @@ import org.springframework.web.util.UrlPathHelper; * UriComponentsBuilder with additional static factory methods to create links * based on the current HttpServletRequest. * - *

Note: This class extracts and uses values from the headers - * "Forwarded" (RFC 7239), - * or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if - * "Forwarded" is not found, in order to reflect the client-originated protocol - * and address. As an alternative consider using the - * {@link org.springframework.web.filter.ForwardedHeaderFilter} to have such - * headers extracted once and removed, or removed only (without being used). - * See the reference for further information including security considerations. + *

Note: This class uses values from "Forwarded" + * (RFC 7239), + * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, + * if present, in order to reflect the client-originated protocol and address. + * Consider using the {@code ForwardedHeaderFilter} in order to choose from a + * central place whether to extract and use, or to discard such headers. + * See the Spring Framework reference for more on this filter. * * @author Rossen Stoyanchev * @since 3.1 diff --git a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd index 071ecae722..df49cfe09a 100644 --- a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd +++ b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc.xsd @@ -1331,6 +1331,12 @@ diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index 9bb0289f87..52a32b59eb 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -854,6 +854,44 @@ views through the <>. Default view always selected and used if they match the requested media type. +[[webflux-filters]] +== Filters +[.small]#<># + +As part of the <>, the `spring-web` module provides a number of +`WebFilter` implementations. + + + +[[webflux-filters-forwarded-headers]] +=== Forwarded Headers +[.small]#<># + +As a request goes through proxies such as load balancers the host, port, and +scheme may change presenting a challenge for applications that need to create links +to resources since the links should reflect the host, port, and scheme of the +original request as seen from a client perspective. + +https://tools.ietf.org/html/rfc7239[RFC 7239] defines the "Forwarded" HTTP header +for proxies to use to provide information about the original request. There are also +other non-standard headers in use such as "X-Forwarded-Host", "X-Forwarded-Port", +and "X-Forwarded-Proto". + +`ForwardedHeaderFilter` detects, extracts, and uses information from the "Forwarded" +header, or from "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto". +It wraps the request in order to overlay its host, port, and scheme and also "hides" +the forwarded headers for subsequent processing. + +Note that there are security considerations when using forwarded headers as explained +in Section 8 of RFC 7239. At the application level it is difficult to determine whether +forwarded headers can be trusted or not. This is why the network upstream should be +configured correctly to filter out untrusted forwarded headers from the outside. + +Applications that don't have a proxy and don't need to use forwarded headers can +configure the `ForwardedHeaderFilter` to remove and ignore such headers. + + + [[webflux-controller]] diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index e28a993549..fdf561bd19 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -1029,6 +1029,7 @@ Once the Servlet 3.0 configuration is in place, simply add a bean of type [[filters]] == Filters +[.small]#<># The `spring-web` module provides some useful filters. @@ -1048,8 +1049,9 @@ available through the `ServletRequest.getParameter{asterisk}()` family of method -[[filters-forwarded-headers]] +[[webflux-filters-forwarded-headers]] === Forwarded Headers +[.small]#<># As a request goes through proxies such as load balancers the host, port, and scheme may change presenting a challenge for applications that need to create links