Issue #3782 X-Forwarded-Port can be remote or local

Improved names and javadoc after review.

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2019-06-17 14:00:30 +02:00
parent 9cf8cf3c0d
commit e7e63a5617
4 changed files with 28 additions and 13 deletions

View File

@ -6,13 +6,13 @@
<New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"> <New class="org.eclipse.jetty.server.ForwardedRequestCustomizer">
<Set name="forwardedOnly"><Property name="jetty.httpConfig.forwardedOnly" default="false"/></Set> <Set name="forwardedOnly"><Property name="jetty.httpConfig.forwardedOnly" default="false"/></Set>
<Set name="proxyAsAuthority"><Property name="jetty.httpConfig.forwardedProxyAsAuthority" default="false"/></Set> <Set name="proxyAsAuthority"><Property name="jetty.httpConfig.forwardedProxyAsAuthority" default="false"/></Set>
<Set name="forwardedPortAsAuthority"><Property name="jetty.httpConfig.forwardedPortAsAuthority" default="true"/></Set>
<Set name="forwardedHeader"><Property name="jetty.httpConfig.forwardedHeader" default="Forwarded"/></Set> <Set name="forwardedHeader"><Property name="jetty.httpConfig.forwardedHeader" default="Forwarded"/></Set>
<Set name="forwardedHostHeader"><Property name="jetty.httpConfig.forwardedHostHeader" default="X-Forwarded-Host"/></Set> <Set name="forwardedHostHeader"><Property name="jetty.httpConfig.forwardedHostHeader" default="X-Forwarded-Host"/></Set>
<Set name="forwardedServerHeader"><Property name="jetty.httpConfig.forwardedServerHeader" default="X-Forwarded-Server"/></Set> <Set name="forwardedServerHeader"><Property name="jetty.httpConfig.forwardedServerHeader" default="X-Forwarded-Server"/></Set>
<Set name="forwardedProtoHeader"><Property name="jetty.httpConfig.forwardedProtoHeader" default="X-Forwarded-Proto"/></Set> <Set name="forwardedProtoHeader"><Property name="jetty.httpConfig.forwardedProtoHeader" default="X-Forwarded-Proto"/></Set>
<Set name="forwardedForHeader"><Property name="jetty.httpConfig.forwardedForHeader" default="X-Forwarded-For"/></Set> <Set name="forwardedForHeader"><Property name="jetty.httpConfig.forwardedForHeader" default="X-Forwarded-For"/></Set>
<Set name="forwardedPortHeader"><Property name="jetty.httpConfig.forwardedPortHeader" default="X-Forwarded-Port"/></Set> <Set name="forwardedPortHeader"><Property name="jetty.httpConfig.forwardedPortHeader" default="X-Forwarded-Port"/></Set>
<Set name="forwardedPortHeaderRemote"><Property name="jetty.httpConfig.forwardedPortHeaderRemote" default="false"/></Set>
<Set name="forwardedHttpsHeader"><Property name="jetty.httpConfig.forwardedHttpsHeader" default="X-Proxied-Https"/></Set> <Set name="forwardedHttpsHeader"><Property name="jetty.httpConfig.forwardedHttpsHeader" default="X-Proxied-Https"/></Set>
<Set name="forwardedSslSessionIdHeader"><Property name="jetty.httpConfig.forwardedSslSessionIdHeader" default="Proxy-ssl-id" /></Set> <Set name="forwardedSslSessionIdHeader"><Property name="jetty.httpConfig.forwardedSslSessionIdHeader" default="Proxy-ssl-id" /></Set>
<Set name="forwardedCipherSuiteHeader"><Property name="jetty.httpConfig.forwardedCipherSuiteHeader" default="Proxy-auth-cert"/></Set> <Set name="forwardedCipherSuiteHeader"><Property name="jetty.httpConfig.forwardedCipherSuiteHeader" default="Proxy-auth-cert"/></Set>

View File

@ -16,15 +16,21 @@ etc/jetty-http-forwarded.xml
[ini-template] [ini-template]
### ForwardedRequestCustomizer Configuration ### ForwardedRequestCustomizer Configuration
## If true, only the RFC7239 Forwarded header is accepted
# jetty.httpConfig.forwardedOnly=false # jetty.httpConfig.forwardedOnly=false
## if true, the proxy address obtained from X-Forwarded-Server or RFC7239 is used as the request authority.
# jetty.httpConfig.forwardedProxyAsAuthority=false # jetty.httpConfig.forwardedProxyAsAuthority=false
## if true, the X-Forwarded-Port header applies to the authority, else it applies to the remote client address
# jetty.httpConfig.forwardedPortAsAuthority=true
# jetty.httpConfig.forwardedHeader=Forwarded # jetty.httpConfig.forwardedHeader=Forwarded
# jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host # jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host
# jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server # jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server
# jetty.httpConfig.forwardedProtoHeader=X-Forwarded-Proto # jetty.httpConfig.forwardedProtoHeader=X-Forwarded-Proto
# jetty.httpConfig.forwardedForHeader=X-Forwarded-For # jetty.httpConfig.forwardedForHeader=X-Forwarded-For
# jetty.httpConfig.forwardedPortHeader=X-Forwarded-Port # jetty.httpConfig.forwardedPortHeader=X-Forwarded-Port
# jetty.httpConfig.forwardedPortHeaderRemote=false
# jetty.httpConfig.forwardedHttpsHeader=X-Proxied-Https # jetty.httpConfig.forwardedHttpsHeader=X-Proxied-Https
# jetty.httpConfig.forwardedSslSessionIdHeader=Proxy-ssl-id # jetty.httpConfig.forwardedSslSessionIdHeader=Proxy-ssl-id
# jetty.httpConfig.forwardedCipherSuiteHeader=Proxy-auth-cert # jetty.httpConfig.forwardedCipherSuiteHeader=Proxy-auth-cert

View File

@ -67,17 +67,17 @@ public class ForwardedRequestCustomizer implements Customizer
private static final Logger LOG = Log.getLogger(ForwardedRequestCustomizer.class); private static final Logger LOG = Log.getLogger(ForwardedRequestCustomizer.class);
private HostPortHttpField _forcedHost; private HostPortHttpField _forcedHost;
private boolean _proxyAsAuthority = false;
private boolean _forwardedPortAsAuthority = true;
private String _forwardedHeader = HttpHeader.FORWARDED.toString(); private String _forwardedHeader = HttpHeader.FORWARDED.toString();
private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString(); private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString(); private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString(); private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString(); private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
private String _forwardedPortHeader = HttpHeader.X_FORWARDED_PORT.toString(); private String _forwardedPortHeader = HttpHeader.X_FORWARDED_PORT.toString();
private boolean _forwardedPortHeaderRemote = false;
private String _forwardedHttpsHeader = "X-Proxied-Https"; private String _forwardedHttpsHeader = "X-Proxied-Https";
private String _forwardedCipherSuiteHeader = "Proxy-auth-cert"; private String _forwardedCipherSuiteHeader = "Proxy-auth-cert";
private String _forwardedSslSessionIdHeader = "Proxy-ssl-id"; private String _forwardedSslSessionIdHeader = "Proxy-ssl-id";
private boolean _proxyAsAuthority = false;
private boolean _sslIsSecure = true; private boolean _sslIsSecure = true;
private Trie<MethodHandle> _handles; private Trie<MethodHandle> _handles;
@ -252,14 +252,23 @@ public class ForwardedRequestCustomizer implements Customizer
} }
} }
public boolean isForwardedPortHeaderRemote() /**
* @return if true, the X-Forwarded-Port header applies to the authority,
* else it applies to the remote client address
*/
public boolean getForwardedPortAsAuthority()
{ {
return _forwardedPortHeaderRemote; return _forwardedPortAsAuthority;
} }
public void setForwardedPortHeaderRemote(boolean forwardedPortHeaderRemote) /**
* Set if the X-Forwarded-Port header will be used for Authority
* @param forwardedPortAsAuthority if true, the X-Forwarded-Port header applies to the authority,
* else it applies to the remote client address
*/
public void setForwardedPortAsAuthority(boolean forwardedPortAsAuthority)
{ {
_forwardedPortHeaderRemote = forwardedPortHeaderRemote; _forwardedPortAsAuthority = forwardedPortAsAuthority;
} }
/** /**
@ -563,7 +572,7 @@ public class ForwardedRequestCustomizer implements Customizer
public void handleHost(HttpField field) public void handleHost(HttpField field)
{ {
if (!_forwardedPortHeaderRemote && !StringUtil.isEmpty(_forwardedPortHeader)) if (_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader))
{ {
if (_host == null) if (_host == null)
_host = new PossiblyPartialHostPort(getLeftMost(field.getValue())); _host = new PossiblyPartialHostPort(getLeftMost(field.getValue()));
@ -591,7 +600,7 @@ public class ForwardedRequestCustomizer implements Customizer
public void handleFor(HttpField field) public void handleFor(HttpField field)
{ {
if (_forwardedPortHeaderRemote && !StringUtil.isEmpty(_forwardedPortHeader)) if (!_forwardedPortAsAuthority && !StringUtil.isEmpty(_forwardedPortHeader))
{ {
if (_for == null) if (_for == null)
_for = new PossiblyPartialHostPort(getLeftMost(field.getValue())); _for = new PossiblyPartialHostPort(getLeftMost(field.getValue()));
@ -606,7 +615,7 @@ public class ForwardedRequestCustomizer implements Customizer
public void handlePort(HttpField field) public void handlePort(HttpField field)
{ {
if (_forwardedPortHeaderRemote) if (!_forwardedPortAsAuthority)
{ {
if (_for == null) if (_for == null)
_for = new PortSetHostPort(_request.getRemoteHost(), field.getIntValue()); _for = new PortSetHostPort(_request.getRemoteHost(), field.getIntValue());
@ -647,7 +656,7 @@ public class ForwardedRequestCustomizer implements Customizer
break; break;
if (value.startsWith("_") || "unknown".equals(value)) if (value.startsWith("_") || "unknown".equals(value))
break; break;
if (_host == null || !(_host instanceof Rfc7239HostPort)) if (_proxyAsAuthority && (_host == null || !(_host instanceof Rfc7239HostPort)))
_host = new Rfc7239HostPort(value); _host = new Rfc7239HostPort(value);
break; break;
case "for": case "for":

View File

@ -568,7 +568,7 @@ public class ForwardedRequestCustomizerTest
@Test @Test
public void testRemote_Port_For() throws Exception public void testRemote_Port_For() throws Exception
{ {
_customizer.setForwardedPortHeaderRemote(true); _customizer.setForwardedPortAsAuthority(false);
HttpTester.Response response = HttpTester.parseResponse( HttpTester.Response response = HttpTester.parseResponse(
_connector.getResponse( _connector.getResponse(
"GET / HTTP/1.1\n" + "GET / HTTP/1.1\n" +