diff --git a/presto-docs/src/main/sphinx/develop/password-authenticator.rst b/presto-docs/src/main/sphinx/develop/password-authenticator.rst index 026953273dfd0..00a58cc205823 100644 --- a/presto-docs/src/main/sphinx/develop/password-authenticator.rst +++ b/presto-docs/src/main/sphinx/develop/password-authenticator.rst @@ -42,4 +42,4 @@ Example configuration file: custom-property2=custom-value2 Additionally, the coordinator must be configured to use password authentication -and have HTTPS enabled. +and have HTTPS enabled (or HTTPS forwarding enabled). diff --git a/presto-docs/src/main/sphinx/security/ldap.rst b/presto-docs/src/main/sphinx/security/ldap.rst index 287ed189183ce..9585ad7945e49 100644 --- a/presto-docs/src/main/sphinx/security/ldap.rst +++ b/presto-docs/src/main/sphinx/security/ldap.rst @@ -89,6 +89,10 @@ Property Description used to secure TLS. ``http-server.https.keystore.key`` The password for the keystore. This must match the password you specified when creating the keystore. +``http-server.authentication.allow-forwarded-https`` Enable treating forwarded HTTPS requests over HTTP + as secure. Requires the ``X-Forwarded-Proto`` header + to be set to ``https`` on forwarded requests. + Default value is ``false``. ======================================================= ====================================================== Password Authenticator Configuration diff --git a/presto-main/src/main/java/io/prestosql/server/security/AuthenticationFilter.java b/presto-main/src/main/java/io/prestosql/server/security/AuthenticationFilter.java index f6cc9dc60ec91..ed776c1536d56 100644 --- a/presto-main/src/main/java/io/prestosql/server/security/AuthenticationFilter.java +++ b/presto-main/src/main/java/io/prestosql/server/security/AuthenticationFilter.java @@ -14,7 +14,9 @@ package io.prestosql.server.security; import com.google.common.base.Joiner; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; +import com.google.common.net.HttpHeaders; import javax.inject.Inject; import javax.servlet.Filter; @@ -43,12 +45,16 @@ public class AuthenticationFilter implements Filter { + private static final String HTTPS_PROTOCOL = "https"; + private final List authenticators; + private final boolean httpsForwardingEnabled; @Inject - public AuthenticationFilter(List authenticators) + public AuthenticationFilter(List authenticators, SecurityConfig securityConfig) { - this.authenticators = ImmutableList.copyOf(authenticators); + this.authenticators = ImmutableList.copyOf(requireNonNull(authenticators, "authenticators is null")); + this.httpsForwardingEnabled = requireNonNull(securityConfig, "securityConfig is null").getEnableForwardingHttps(); } @Override @@ -65,7 +71,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo HttpServletResponse response = (HttpServletResponse) servletResponse; // skip authentication if non-secure or not configured - if (!request.isSecure() || authenticators.isEmpty()) { + if (!doesRequestSupportAuthentication(request)) { nextFilter.doFilter(request, response); return; } @@ -105,6 +111,17 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo response.sendError(SC_UNAUTHORIZED, Joiner.on(" | ").join(messages)); } + private boolean doesRequestSupportAuthentication(HttpServletRequest request) + { + if (authenticators.isEmpty()) { + return false; + } + if (request.isSecure()) { + return true; + } + return httpsForwardingEnabled && Strings.nullToEmpty(request.getHeader(HttpHeaders.X_FORWARDED_PROTO)).equalsIgnoreCase(HTTPS_PROTOCOL); + } + private static ServletRequest withPrincipal(HttpServletRequest request, Principal principal) { requireNonNull(principal, "principal is null"); diff --git a/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java b/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java index fc31b5b856c61..fba110ba3105a 100644 --- a/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java +++ b/presto-main/src/main/java/io/prestosql/server/security/SecurityConfig.java @@ -32,6 +32,7 @@ public class SecurityConfig private static final Splitter SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings(); private List authenticationTypes = ImmutableList.of(); + private boolean enableForwardingHttps; public enum AuthenticationType { @@ -67,4 +68,17 @@ public SecurityConfig setAuthenticationTypes(String types) .collect(toImmutableList()); return this; } + + public boolean getEnableForwardingHttps() + { + return enableForwardingHttps; + } + + @Config("http-server.authentication.allow-forwarded-https") + @ConfigDescription("Enable forwarding HTTPS requests") + public SecurityConfig setEnableForwardingHttps(boolean enableForwardingHttps) + { + this.enableForwardingHttps = enableForwardingHttps; + return this; + } } diff --git a/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java b/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java index 1a076930d1b11..1d760a56086c4 100644 --- a/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java +++ b/presto-main/src/test/java/io/prestosql/server/security/TestSecurityConfig.java @@ -31,6 +31,7 @@ public class TestSecurityConfig public void testDefaults() { assertRecordedDefaults(recordDefaults(SecurityConfig.class) + .setEnableForwardingHttps(false) .setAuthenticationTypes("")); } @@ -39,9 +40,11 @@ public void testExplicitPropertyMappings() { Map properties = new ImmutableMap.Builder() .put("http-server.authentication.type", "KERBEROS,PASSWORD") + .put("http-server.authentication.allow-forwarded-https", "true") .build(); SecurityConfig expected = new SecurityConfig() + .setEnableForwardingHttps(true) .setAuthenticationTypes(ImmutableList.of(KERBEROS, PASSWORD)); assertFullMapping(properties, expected);