Polish Forwarded header support
This commit is contained in:
@@ -42,19 +42,19 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers in order to wrap
|
||||
* and override the following from the request and response:
|
||||
* {@link HttpServletRequest#getServerName() getServerName()},
|
||||
* {@link HttpServletRequest#getServerPort() getServerPort()},
|
||||
* {@link HttpServletRequest#getScheme() getScheme()},
|
||||
* {@link HttpServletRequest#isSecure() isSecure()}, and
|
||||
* {@link HttpServletResponse#sendRedirect(String) sendRedirect(String)}.
|
||||
* In effect the wrapped request and response reflect the client-originated
|
||||
* protocol and address.
|
||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers, wrap the request
|
||||
* and response, and make they reflect the client-originated protocol and
|
||||
* address in the following methods:
|
||||
* <ul>
|
||||
* <li>{@link HttpServletRequest#getServerName() getServerName()}
|
||||
* <li>{@link HttpServletRequest#getServerPort() getServerPort()}
|
||||
* <li>{@link HttpServletRequest#getScheme() getScheme()}
|
||||
* <li>{@link HttpServletRequest#isSecure() isSecure()}
|
||||
* <li>{@link HttpServletResponse#sendRedirect(String) sendRedirect(String)}.
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>Note:</strong> This filter can also be used in a
|
||||
* {@link #setRemoveOnly removeOnly} mode where "Forwarded" and "X-Forwarded-*"
|
||||
* headers are only eliminated without being used.
|
||||
* <p>This filter can also be used in a {@link #setRemoveOnly removeOnly} mode
|
||||
* where "Forwarded" and "X-Forwarded-*" headers are eliminated, and not used.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Eddú Meléndez
|
||||
@@ -117,7 +117,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
|
||||
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||
for (String headerName : FORWARDED_HEADER_NAMES) {
|
||||
if (request.getHeader(headerName) != null) {
|
||||
return false;
|
||||
@@ -141,15 +141,18 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
|
||||
if (this.removeOnly) {
|
||||
ForwardedHeaderRemovingRequest theRequest = new ForwardedHeaderRemovingRequest(request);
|
||||
filterChain.doFilter(theRequest, response);
|
||||
ForwardedHeaderRemovingRequest wrappedRequest = new ForwardedHeaderRemovingRequest(request);
|
||||
filterChain.doFilter(wrappedRequest, response);
|
||||
}
|
||||
else {
|
||||
HttpServletRequest theRequest = new ForwardedHeaderExtractingRequest(request, this.pathHelper);
|
||||
HttpServletResponse theResponse = (this.relativeRedirects ?
|
||||
HttpServletRequest wrappedRequest =
|
||||
new ForwardedHeaderExtractingRequest(request, this.pathHelper);
|
||||
|
||||
HttpServletResponse wrappedResponse = this.relativeRedirects ?
|
||||
RelativeRedirectResponseWrapper.wrapIfNecessary(response, HttpStatus.SEE_OTHER) :
|
||||
new ForwardedHeaderExtractingResponse(response, theRequest));
|
||||
filterChain.doFilter(theRequest, theResponse);
|
||||
new ForwardedHeaderExtractingResponse(response, wrappedRequest);
|
||||
|
||||
filterChain.doFilter(wrappedRequest, wrappedResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +224,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||
|
||||
private final String requestUrl;
|
||||
|
||||
public ForwardedHeaderExtractingRequest(HttpServletRequest request, UrlPathHelper pathHelper) {
|
||||
|
||||
ForwardedHeaderExtractingRequest(HttpServletRequest request, UrlPathHelper pathHelper) {
|
||||
super(request);
|
||||
|
||||
HttpRequest httpRequest = new ServletServerHttpRequest(request);
|
||||
@@ -257,6 +261,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getScheme() {
|
||||
@@ -302,11 +307,13 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
public ForwardedHeaderExtractingResponse(HttpServletResponse response, HttpServletRequest request) {
|
||||
|
||||
ForwardedHeaderExtractingResponse(HttpServletResponse response, HttpServletRequest request) {
|
||||
super(response);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendRedirect(String location) throws IOException {
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -31,17 +31,16 @@ import org.springframework.web.server.WebFilterChain;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers in order to change
|
||||
* and override {@link ServerHttpRequest#getURI()}.
|
||||
* In effect the request URI will reflect the client-originated
|
||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers, and use them to
|
||||
* override {@link ServerHttpRequest#getURI()} to reflect the client-originated
|
||||
* protocol and address.
|
||||
*
|
||||
* <p><strong>Note:</strong> This filter can also be used in a
|
||||
* {@link #setRemoveOnly removeOnly} mode where "Forwarded" and "X-Forwarded-*"
|
||||
* headers are only eliminated without being used.
|
||||
* <p>This filter can also be used in a {@link #setRemoveOnly removeOnly} mode
|
||||
* where "Forwarded" and "X-Forwarded-*" headers are eliminated, and not used.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
||||
* @since 5.0
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
||||
*/
|
||||
public class ForwardedHeaderFilter implements WebFilter {
|
||||
|
||||
@@ -55,8 +54,10 @@ public class ForwardedHeaderFilter implements WebFilter {
|
||||
FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix");
|
||||
}
|
||||
|
||||
|
||||
private boolean removeOnly;
|
||||
|
||||
|
||||
/**
|
||||
* Enables mode in which any "Forwarded" or "X-Forwarded-*" headers are
|
||||
* removed only and the information in them ignored.
|
||||
@@ -66,6 +67,7 @@ public class ForwardedHeaderFilter implements WebFilter {
|
||||
this.removeOnly = removeOnly;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
|
||||
@@ -73,31 +75,29 @@ public class ForwardedHeaderFilter implements WebFilter {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
ServerWebExchange mutatedExchange;
|
||||
|
||||
if (this.removeOnly) {
|
||||
ServerWebExchange withoutForwardHeaders = exchange.mutate()
|
||||
.request(builder -> builder.headers(
|
||||
headers -> {
|
||||
for (String headerName : FORWARDED_HEADER_NAMES) {
|
||||
headers.remove(headerName);
|
||||
}
|
||||
})).build();
|
||||
return chain.filter(withoutForwardHeaders);
|
||||
mutatedExchange = exchange.mutate().request(builder ->
|
||||
builder.headers(headers -> {
|
||||
FORWARDED_HEADER_NAMES.forEach(headers::remove);
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
else {
|
||||
URI uri = UriComponentsBuilder.fromHttpRequest(exchange.getRequest()).build().toUri();
|
||||
String prefix = getForwardedPrefix(exchange.getRequest().getHeaders());
|
||||
|
||||
ServerWebExchange withChangedUri = exchange.mutate()
|
||||
.request(builder -> {
|
||||
builder.uri(uri);
|
||||
if (prefix != null) {
|
||||
builder.path(prefix + uri.getPath());
|
||||
builder.contextPath(prefix);
|
||||
}
|
||||
}).build();
|
||||
return chain.filter(withChangedUri);
|
||||
mutatedExchange = exchange.mutate().request(builder -> {
|
||||
builder.uri(uri);
|
||||
if (prefix != null) {
|
||||
builder.path(prefix + uri.getPath());
|
||||
builder.contextPath(prefix);
|
||||
}
|
||||
}).build();
|
||||
}
|
||||
|
||||
return chain.filter(mutatedExchange);
|
||||
}
|
||||
|
||||
private boolean shouldNotFilter(ServerHttpRequest request) {
|
||||
|
||||
Reference in New Issue
Block a user