Improve docs on forwarded headers
Issue: SPR-15612
This commit is contained in:
@@ -274,7 +274,7 @@ public class UriComponentsBuilder implements Cloneable {
|
||||
/**
|
||||
* Create a new {@code UriComponents} object from the URI associated with
|
||||
* the given HttpRequest while also overlaying with values from the headers
|
||||
* "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>,
|
||||
* "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
|
||||
* or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if
|
||||
* "Forwarded" is not found.
|
||||
* @param request the source request
|
||||
|
||||
@@ -68,18 +68,28 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Creates instances of {@link org.springframework.web.util.UriComponentsBuilder}
|
||||
* by pointing to Spring MVC controllers and {@code @RequestMapping} methods.
|
||||
* by pointing to {@code @RequestMapping} methods on Spring MVC controllers.
|
||||
*
|
||||
* <p>The static {@code fromXxx(...)} methods prepare links relative to the
|
||||
* current request as determined by a call to
|
||||
* <p>There are several groups of methods:
|
||||
* <ul>
|
||||
* <li>Static {@code fromXxx(...)} methods to prepare links using information
|
||||
* from the current request as determined by a call to
|
||||
* {@link org.springframework.web.servlet.support.ServletUriComponentsBuilder#fromCurrentServletMapping()}.
|
||||
* <li>Static {@code fromXxx(UriComponentsBuilder,...)} methods can be given
|
||||
* a baseUrl when operating outside the context of a request.
|
||||
* <li>Instance-based {@code withXxx(...)} methods where an instance of
|
||||
* MvcUriComponentsBuilder is created with a baseUrl via
|
||||
* {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}.
|
||||
* </ul>
|
||||
*
|
||||
* <p>The static {@code fromXxx(UriComponentsBuilder,...)} methods can be given
|
||||
* the baseUrl when operating outside the context of a request.
|
||||
*
|
||||
* <p>You can also create an MvcUriComponentsBuilder instance with a baseUrl
|
||||
* via {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}
|
||||
* and then use the non-static {@code withXxx(...)} method variants.
|
||||
* <p><strong>Note:</strong> This class extracts and uses values from the headers
|
||||
* "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
|
||||
* 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.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -140,6 +150,8 @@ public class MvcUriComponentsBuilder {
|
||||
* Create a {@link UriComponentsBuilder} from the mapping of a controller class
|
||||
* and current request information including Servlet mapping. If the controller
|
||||
* contains multiple mappings, only the first one is used.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param controllerType the controller to build a URI for
|
||||
* @return a UriComponentsBuilder instance (never {@code null})
|
||||
*/
|
||||
@@ -152,6 +164,8 @@ public class MvcUriComponentsBuilder {
|
||||
* {@code UriComponentsBuilder} representing the base URL. This is useful
|
||||
* when using MvcUriComponentsBuilder outside the context of processing a
|
||||
* request or to apply a custom baseUrl not matching the current request.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param builder the builder for the base URL; the builder will be cloned
|
||||
* and therefore not modified and may be re-used for further calls.
|
||||
* @param controllerType the controller to build a URI for
|
||||
@@ -169,6 +183,8 @@ public class MvcUriComponentsBuilder {
|
||||
* Create a {@link UriComponentsBuilder} from the mapping of a controller
|
||||
* method and an array of method argument values. This method delegates
|
||||
* to {@link #fromMethod(Class, Method, Object...)}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param controllerType the controller
|
||||
* @param methodName the method name
|
||||
* @param args the argument values
|
||||
@@ -188,6 +204,8 @@ public class MvcUriComponentsBuilder {
|
||||
* accepts a {@code UriComponentsBuilder} representing the base URL. This is
|
||||
* useful when using MvcUriComponentsBuilder outside the context of processing
|
||||
* a request or to apply a custom baseUrl not matching the current request.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param builder the builder for the base URL; the builder will be cloned
|
||||
* and therefore not modified and may be re-used for further calls.
|
||||
* @param controllerType the controller
|
||||
@@ -235,6 +253,10 @@ public class MvcUriComponentsBuilder {
|
||||
* controller.getAddressesForCountry("US")
|
||||
* builder = MvcUriComponentsBuilder.fromMethodCall(controller);
|
||||
* </pre>
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*
|
||||
* @param info either the value returned from a "mock" controller
|
||||
* invocation or the "mock" controller itself after an invocation
|
||||
* @return a UriComponents instance
|
||||
@@ -253,6 +275,8 @@ public class MvcUriComponentsBuilder {
|
||||
* {@code UriComponentsBuilder} representing the base URL. This is useful
|
||||
* when using MvcUriComponentsBuilder outside the context of processing a
|
||||
* request or to apply a custom baseUrl not matching the current request.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param builder the builder for the base URL; the builder will be cloned
|
||||
* and therefore not modified and may be re-used for further calls.
|
||||
* @param info either the value returned from a "mock" controller
|
||||
@@ -303,6 +327,10 @@ public class MvcUriComponentsBuilder {
|
||||
* </pre>
|
||||
* <p>Note that it's not necessary to specify all arguments. Only the ones
|
||||
* required to prepare the URL, mainly {@code @RequestParam} and {@code @PathVariable}).
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*
|
||||
* @param mappingName the mapping name
|
||||
* @return a builder to prepare the URI String
|
||||
* @throws IllegalArgumentException if the mapping name is not found or
|
||||
@@ -318,6 +346,8 @@ public class MvcUriComponentsBuilder {
|
||||
* {@code UriComponentsBuilder} representing the base URL. This is useful
|
||||
* when using MvcUriComponentsBuilder outside the context of processing a
|
||||
* request or to apply a custom baseUrl not matching the current request.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param builder the builder for the base URL; the builder will be cloned
|
||||
* and therefore not modified and may be re-used for further calls.
|
||||
* @param name the mapping name
|
||||
@@ -350,6 +380,8 @@ public class MvcUriComponentsBuilder {
|
||||
* {@link org.springframework.web.method.support.UriComponentsContributor
|
||||
* UriComponentsContributor}) while remaining argument values are ignored and
|
||||
* can be {@code null}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param controllerType the controller type
|
||||
* @param method the controller method
|
||||
* @param args argument values for the controller method
|
||||
@@ -366,6 +398,8 @@ public class MvcUriComponentsBuilder {
|
||||
* This is useful when using MvcUriComponentsBuilder outside the context of
|
||||
* processing a request or to apply a custom baseUrl not matching the
|
||||
* current request.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param baseUrl the builder for the base URL; the builder will be cloned
|
||||
* and therefore not modified and may be re-used for further calls.
|
||||
* @param controllerType the controller type
|
||||
@@ -557,6 +591,9 @@ public class MvcUriComponentsBuilder {
|
||||
* <pre class="code">
|
||||
* MvcUriComponentsBuilder.fromMethodCall(on(FooController.class).getFoo(1)).build();
|
||||
* </pre>
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*
|
||||
* @param controllerType the target controller
|
||||
*/
|
||||
public static <T> T on(Class<T> controllerType) {
|
||||
@@ -579,6 +616,8 @@ public class MvcUriComponentsBuilder {
|
||||
* fooController.saveFoo(2, null);
|
||||
* builder = MvcUriComponentsBuilder.fromMethodCall(fooController);
|
||||
* </pre>
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @param controllerType the target controller
|
||||
*/
|
||||
public static <T> T controller(Class<T> controllerType) {
|
||||
@@ -634,6 +673,8 @@ public class MvcUriComponentsBuilder {
|
||||
/**
|
||||
* An alternative to {@link #fromController(Class)} for use with an instance
|
||||
* of this class created via a call to {@link #relativeTo}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @since 4.2
|
||||
*/
|
||||
public UriComponentsBuilder withController(Class<?> controllerType) {
|
||||
@@ -643,6 +684,8 @@ public class MvcUriComponentsBuilder {
|
||||
/**
|
||||
* An alternative to {@link #fromMethodName(Class, String, Object...)}} for
|
||||
* use with an instance of this class created via {@link #relativeTo}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @since 4.2
|
||||
*/
|
||||
public UriComponentsBuilder withMethodName(Class<?> controllerType, String methodName, Object... args) {
|
||||
@@ -652,6 +695,8 @@ public class MvcUriComponentsBuilder {
|
||||
/**
|
||||
* An alternative to {@link #fromMethodCall(Object)} for use with an instance
|
||||
* of this class created via {@link #relativeTo}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @since 4.2
|
||||
*/
|
||||
public UriComponentsBuilder withMethodCall(Object invocationInfo) {
|
||||
@@ -661,6 +706,8 @@ public class MvcUriComponentsBuilder {
|
||||
/**
|
||||
* An alternative to {@link #fromMappingName(String)} for use with an instance
|
||||
* of this class created via {@link #relativeTo}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @since 4.2
|
||||
*/
|
||||
public MethodArgumentBuilder withMappingName(String mappingName) {
|
||||
@@ -670,6 +717,8 @@ public class MvcUriComponentsBuilder {
|
||||
/**
|
||||
* An alternative to {@link #fromMethod(Class, Method, Object...)}
|
||||
* for use with an instance of this class created via {@link #relativeTo}.
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
* @since 4.2
|
||||
*/
|
||||
public UriComponentsBuilder withMethod(Class<?> controllerType, Method method, Object... args) {
|
||||
|
||||
@@ -32,7 +32,17 @@ import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* A UriComponentsBuilder that extracts information from the HttpServletRequest.
|
||||
* UriComponentsBuilder with additional static factory methods to create links
|
||||
* based on the current HttpServletRequest.
|
||||
*
|
||||
* <p><strong>Note:</strong> This class extracts and uses values from the headers
|
||||
* "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
|
||||
* 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.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
@@ -69,6 +79,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Prepare a builder from the host, port, scheme, and context path of the
|
||||
* given HttpServletRequest.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromContextPath(HttpServletRequest request) {
|
||||
ServletUriComponentsBuilder builder = initFromRequest(request);
|
||||
@@ -83,6 +96,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
* will end with "/main". If the servlet is mapped otherwise, e.g.
|
||||
* {@code "/"} or {@code "*.do"}, the result will be the same as
|
||||
* if calling {@link #fromContextPath(HttpServletRequest)}.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromServletMapping(HttpServletRequest request) {
|
||||
ServletUriComponentsBuilder builder = fromContextPath(request);
|
||||
@@ -95,6 +111,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Prepare a builder from the host, port, scheme, and path (but not the query)
|
||||
* of the HttpServletRequest.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromRequestUri(HttpServletRequest request) {
|
||||
ServletUriComponentsBuilder builder = initFromRequest(request);
|
||||
@@ -105,6 +124,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Prepare a builder by copying the scheme, host, port, path, and
|
||||
* query string of an HttpServletRequest.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromRequest(HttpServletRequest request) {
|
||||
ServletUriComponentsBuilder builder = initFromRequest(request);
|
||||
@@ -153,6 +175,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Same as {@link #fromContextPath(HttpServletRequest)} except the
|
||||
* request is obtained through {@link RequestContextHolder}.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromCurrentContextPath() {
|
||||
return fromContextPath(getCurrentRequest());
|
||||
@@ -161,6 +186,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Same as {@link #fromServletMapping(HttpServletRequest)} except the
|
||||
* request is obtained through {@link RequestContextHolder}.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromCurrentServletMapping() {
|
||||
return fromServletMapping(getCurrentRequest());
|
||||
@@ -169,6 +197,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Same as {@link #fromRequestUri(HttpServletRequest)} except the
|
||||
* request is obtained through {@link RequestContextHolder}.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromCurrentRequestUri() {
|
||||
return fromRequestUri(getCurrentRequest());
|
||||
@@ -177,6 +208,9 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
/**
|
||||
* Same as {@link #fromRequest(HttpServletRequest)} except the
|
||||
* request is obtained through {@link RequestContextHolder}.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
|
||||
* and "X-Forwarded-*" headers if found. See class-level docs.
|
||||
*/
|
||||
public static ServletUriComponentsBuilder fromCurrentRequest() {
|
||||
return fromRequest(getCurrentRequest());
|
||||
|
||||
@@ -3389,6 +3389,38 @@ with a base URL and then use the instance-based "withXxx" methods. For example:
|
||||
----
|
||||
|
||||
|
||||
[[mvc-links-to-controllers-forwarded-headers]]
|
||||
=== Working with "Forwarded" and "X-Forwarded-*" Headers
|
||||
|
||||
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".
|
||||
|
||||
Both `ServletUriComponentsBuilder` and `MvcUriComponentsBuilder` detect, extract, and use
|
||||
information from the "Forwarded" header, or from "X-Forwarded-Host", "X-Forwarded-Port",
|
||||
and "X-Forwarded-Proto" if "Forwarded" is not present, so that the resulting links reflect
|
||||
the original request.
|
||||
|
||||
The `ForwardedHeaderFilter` provides an alternative to do the same once and globally for
|
||||
the entire application. The filter wraps the request in order to overlay host, port, and
|
||||
scheme information and also "hides" any 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.
|
||||
|
||||
|
||||
|
||||
[[mvc-links-to-controllers-from-views]]
|
||||
=== Building URIs to Controllers and methods from views
|
||||
|
||||
|
||||
Reference in New Issue
Block a user