This is an automated email from the ASF dual-hosted git repository. agozhiy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/drill.git
commit c5297911de21ee874e785492a967c6f875090e20 Author: Dobes Vandermeer <[email protected]> AuthorDate: Fri Feb 7 16:47:27 2020 -0800 DRILL-7562: Support HTTP Basic authentication for REST API calls This can greatly simplify the development of HTTP clients, as well as use from the command line using curl/wget, since you don't have to deal with storing the session cookie. closes #1972 --- .../src/main/resources/drill-override-example.conf | 4 +-- .../auth/DrillHttpConstraintSecurityHandler.java | 40 ++++++++++++++-------- .../auth/DrillHttpSecurityHandlerProvider.java | 9 +++++ .../exec/server/rest/auth/FormSecurityHandler.java | 9 ++--- ...dler.java => HttpBasicAuthSecurityHandler.java} | 20 +++++------ 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/distribution/src/main/resources/drill-override-example.conf b/distribution/src/main/resources/drill-override-example.conf index e72396c..0c04175 100644 --- a/distribution/src/main/resources/drill-override-example.conf +++ b/distribution/src/main/resources/drill-override-example.conf @@ -103,8 +103,8 @@ drill.exec: { }, auth: { # Http Auth mechanisms to configure. If not provided but user.auth is enabled - # then default value is FORM. - mechanisms: ["FORM", "SPNEGO"], + # then default value is ["FORM"]. + mechanisms: ["BASIC", "FORM", "SPNEGO"], # Spnego principal to be used by WebServer when Spnego authentication is enabled. spnego.principal: "HTTP://<localhost>" # Location to keytab file for above spnego principal diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpConstraintSecurityHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpConstraintSecurityHandler.java index 8ba6ddf..99ca966 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpConstraintSecurityHandler.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpConstraintSecurityHandler.java @@ -17,6 +17,7 @@ */ package org.apache.drill.exec.server.rest.auth; +import org.apache.drill.exec.rpc.security.plain.PlainFactory; import org.apache.drill.shaded.guava.com.google.common.collect.ImmutableSet; import org.apache.drill.common.exceptions.DrillException; import org.apache.drill.exec.server.DrillbitContext; @@ -38,24 +39,33 @@ import static org.apache.drill.exec.server.rest.auth.DrillUserPrincipal.AUTHENTI **/ public abstract class DrillHttpConstraintSecurityHandler extends ConstraintSecurityHandler { - @Override - public void doStart() throws Exception { - super.doStart(); - } + @Override + public void doStart() throws Exception { + super.doStart(); + } - @Override - public void doStop() throws Exception { - super.doStop(); - } + @Override + public void doStop() throws Exception { + super.doStop(); + } + + public abstract void doSetup(DrillbitContext dbContext) throws DrillException; - public abstract void doSetup(DrillbitContext dbContext) throws DrillException; + public void setup(LoginAuthenticator authenticator, LoginService loginService) { + final Set<String> knownRoles = ImmutableSet.of(AUTHENTICATED_ROLE, ADMIN_ROLE); + setConstraintMappings(Collections.<ConstraintMapping>emptyList(), knownRoles); + setAuthenticator(authenticator); + setLoginService(loginService); + } - public void setup(LoginAuthenticator authenticator, LoginService loginService) { - final Set<String> knownRoles = ImmutableSet.of(AUTHENTICATED_ROLE, ADMIN_ROLE); - setConstraintMappings(Collections.<ConstraintMapping>emptyList(), knownRoles); - setAuthenticator(authenticator); - setLoginService(loginService); + protected void requireAuthProvider(DrillbitContext dbContext, String name) throws DrillException { + // Check if PAMAuthenticator is available or not which is required for FORM authentication + if (!dbContext.getAuthProvider().containsFactory(PlainFactory.SIMPLE_NAME)) { + throw new DrillException(String.format("%1$s auth mechanism was configured but %2$s mechanism is not enabled to provide an " + + "authenticator. Please configure user authentication with %2$s mechanism and authenticator to use " + + "%1$s authentication", getImplName(), name)); } + } - public abstract String getImplName(); + public abstract String getImplName(); } \ No newline at end of file diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpSecurityHandlerProvider.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpSecurityHandlerProvider.java index e95a057..e3087ca 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpSecurityHandlerProvider.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillHttpSecurityHandlerProvider.java @@ -27,6 +27,7 @@ import org.apache.drill.exec.exception.DrillbitStartupException; import org.apache.drill.exec.rpc.security.AuthStringUtil; import org.apache.drill.exec.server.DrillbitContext; import org.apache.drill.exec.server.rest.WebServerConstants; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.security.authentication.SessionAuthentication; import org.eclipse.jetty.server.Handler; @@ -139,10 +140,14 @@ public class DrillHttpSecurityHandlerProvider extends ConstraintSecurityHandler if (isSpnegoEnabled() && (!isFormEnabled() || uri.equals(WebServerConstants.SPENGO_LOGIN_RESOURCE_PATH))) { securityHandler = securityHandlers.get(Constraint.__SPNEGO_AUTH); securityHandler.handle(target, baseRequest, request, response); + } else if(isBasicEnabled() && request.getHeader(HttpHeader.AUTHORIZATION.asString()) != null) { + securityHandler = securityHandlers.get(Constraint.__BASIC_AUTH); + securityHandler.handle(target, baseRequest, request, response); } else if (isFormEnabled()) { securityHandler = securityHandlers.get(Constraint.__FORM_AUTH); securityHandler.handle(target, baseRequest, request, response); } + } // If user has logged in, use the corresponding handler to handle the request else { @@ -175,6 +180,10 @@ public class DrillHttpSecurityHandlerProvider extends ConstraintSecurityHandler return securityHandlers.containsKey(Constraint.__FORM_AUTH); } + public boolean isBasicEnabled() { + return securityHandlers.containsKey(Constraint.__BASIC_AUTH); + } + /** * Return's list of configured mechanisms for HTTP authentication. For backward * compatibility if authentication is enabled it will include FORM mechanism by default. diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java index 2c19d41..8169a40 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java @@ -33,15 +33,10 @@ public class FormSecurityHandler extends DrillHttpConstraintSecurityHandler { @Override public void doSetup(DrillbitContext dbContext) throws DrillException { - // Check if PAMAuthenticator is available or not which is required for FORM authentication - if (!dbContext.getAuthProvider().containsFactory(PlainFactory.SIMPLE_NAME)) { - throw new DrillException("FORM mechanism was configured but PLAIN mechanism is not enabled to provide an " + - "authenticator. Please configure user authentication with PLAIN mechanism and authenticator to use " + - "FORM authentication"); - } + requireAuthProvider(dbContext, PlainFactory.SIMPLE_NAME); setup(new FormAuthenticator(WebServerConstants.FORM_LOGIN_RESOURCE_PATH, - WebServerConstants.FORM_LOGIN_RESOURCE_PATH, true), new DrillRestLoginService(dbContext)); + WebServerConstants.FORM_LOGIN_RESOURCE_PATH, true), new DrillRestLoginService(dbContext)); } } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/HttpBasicAuthSecurityHandler.java similarity index 58% copy from exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java copy to exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/HttpBasicAuthSecurityHandler.java index 2c19d41..2657186 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/FormSecurityHandler.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/HttpBasicAuthSecurityHandler.java @@ -20,28 +20,24 @@ package org.apache.drill.exec.server.rest.auth; import org.apache.drill.common.exceptions.DrillException; import org.apache.drill.exec.rpc.security.plain.PlainFactory; import org.apache.drill.exec.server.DrillbitContext; -import org.apache.drill.exec.server.rest.WebServerConstants; -import org.eclipse.jetty.security.authentication.FormAuthenticator; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.util.security.Constraint; -public class FormSecurityHandler extends DrillHttpConstraintSecurityHandler { +/** + * Implement HTTP Basic authentication for REST API access + */ +public class HttpBasicAuthSecurityHandler extends DrillHttpConstraintSecurityHandler { @Override public String getImplName() { - return Constraint.__FORM_AUTH; + return Constraint.__BASIC_AUTH; } @Override public void doSetup(DrillbitContext dbContext) throws DrillException { - // Check if PAMAuthenticator is available or not which is required for FORM authentication - if (!dbContext.getAuthProvider().containsFactory(PlainFactory.SIMPLE_NAME)) { - throw new DrillException("FORM mechanism was configured but PLAIN mechanism is not enabled to provide an " + - "authenticator. Please configure user authentication with PLAIN mechanism and authenticator to use " + - "FORM authentication"); - } + requireAuthProvider(dbContext, PlainFactory.SIMPLE_NAME); - setup(new FormAuthenticator(WebServerConstants.FORM_LOGIN_RESOURCE_PATH, - WebServerConstants.FORM_LOGIN_RESOURCE_PATH, true), new DrillRestLoginService(dbContext)); + setup(new BasicAuthenticator(), new DrillRestLoginService(dbContext)); } }
