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));
   }
 
 }

Reply via email to