Repository: drill Updated Branches: refs/heads/master 5118d0cf5 -> c98edbafb
DRILL-4354: Remove sessions in anonymous (auth disabled) WebUI access Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/c98edbaf Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/c98edbaf Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/c98edbaf Branch: refs/heads/master Commit: c98edbafb9bdf8ed83e9b2df7b9bf09d7e07987b Parents: ae46d26 Author: vkorukanti <[email protected]> Authored: Tue Feb 2 06:48:18 2016 -0800 Committer: vkorukanti <[email protected]> Committed: Wed Mar 2 14:08:51 2016 -0800 ---------------------------------------------------------------------- .../drill/exec/server/rest/DrillRestServer.java | 44 +++++++++- .../drill/exec/server/rest/DrillRoot.java | 4 +- .../exec/server/rest/MetricsResources.java | 4 +- .../drill/exec/server/rest/QueryResources.java | 20 +++-- .../drill/exec/server/rest/StatusResources.java | 6 +- .../exec/server/rest/StorageResources.java | 6 +- .../exec/server/rest/ThreadsResources.java | 4 +- .../server/rest/ViewableWithPermissions.java | 34 ++++---- .../drill/exec/server/rest/WebServer.java | 25 ++---- .../rest/auth/AnonymousAuthenticator.java | 84 -------------------- .../server/rest/auth/AnonymousLoginService.java | 62 --------------- .../server/rest/auth/DrillUserPrincipal.java | 49 +++++++++++- .../server/rest/profile/ProfileResources.java | 6 +- 13 files changed, 148 insertions(+), 200 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java index d8533b0..ceecdb4 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRestServer.java @@ -20,6 +20,7 @@ package org.apache.drill.exec.server.rest; import org.apache.drill.exec.ExecConstants; import org.apache.drill.exec.server.rest.auth.AuthDynamicFeature; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; +import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal.AnonDrillUserPrincipal; import org.apache.drill.exec.server.rest.profile.ProfileResources; import org.apache.drill.exec.store.StoragePluginRegistry; import org.apache.drill.exec.store.sys.PersistentStoreProvider; @@ -29,6 +30,7 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.CommonProperties; import org.glassfish.jersey.internal.util.PropertiesHelper; import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.glassfish.jersey.process.internal.RequestScoped; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ServerProperties; import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature; @@ -57,7 +59,10 @@ public class DrillRestServer extends ResourceConfig { register(MultiPartFeature.class); property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); - if (workManager.getContext().getConfig().getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED)) { + final boolean isAuthEnabled = + workManager.getContext().getConfig().getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED); + + if (isAuthEnabled) { register(LogInLogOutResources.class); register(AuthDynamicFeature.class); register(RolesAllowedDynamicFeature.class); @@ -82,7 +87,12 @@ public class DrillRestServer extends ResourceConfig { bind(workManager.getContext().getLpPersistence().getMapper()).to(ObjectMapper.class); bind(workManager.getContext().getStoreProvider()).to(PersistentStoreProvider.class); bind(workManager.getContext().getStorage()).to(StoragePluginRegistry.class); - bindFactory(DrillUserPrincipalProvider.class).to(DrillUserPrincipal.class); + bind(new UserAuthEnabled(isAuthEnabled)).to(UserAuthEnabled.class); + if (isAuthEnabled) { + bindFactory(DrillUserPrincipalProvider.class).to(DrillUserPrincipal.class); + } else { + bindFactory(AnonDrillUserPrincipalProvider.class).to(DrillUserPrincipal.class); + } } }); } @@ -102,4 +112,34 @@ public class DrillRestServer extends ResourceConfig { // No-Op } } + + // Provider which creates and cleanups DrillUserPrincipal for anonymous (auth disabled) mode + public static class AnonDrillUserPrincipalProvider implements Factory<DrillUserPrincipal> { + @Inject WorkManager workManager; + + @RequestScoped + @Override + public DrillUserPrincipal provide() { + return new AnonDrillUserPrincipal(workManager.getContext()); + } + + @Override + public void dispose(DrillUserPrincipal principal) { + // If this worked it would have been clean to free the resources here, but there are various scenarios + // where dispose never gets called due to bugs in jersey. + } + } + + // Returns whether auth is enabled or not in config + public static class UserAuthEnabled { + private boolean value; + + public UserAuthEnabled(boolean value) { + this.value = value; + } + + public boolean get() { + return value; + } + } } http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java index 2e18a74..d1513fc 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/DrillRoot.java @@ -30,6 +30,7 @@ import javax.xml.bind.annotation.XmlRootElement; import org.apache.drill.common.config.DrillConfig; import org.apache.drill.exec.proto.CoordinationProtos; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.work.WorkManager; import org.glassfish.jersey.server.mvc.Viewable; @@ -41,13 +42,14 @@ import com.google.common.collect.Lists; public class DrillRoot { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillRoot.class); + @Inject UserAuthEnabled authEnabled; @Inject WorkManager work; @Inject SecurityContext sc; @GET @Produces(MediaType.TEXT_HTML) public Viewable getStats() { - return ViewableWithPermissions.create("/rest/index.ftl", sc, getStatsJSON()); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/index.ftl", sc, getStatsJSON()); } @GET http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/MetricsResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/MetricsResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/MetricsResources.java index de8523f..db363b6 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/MetricsResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/MetricsResources.java @@ -25,6 +25,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.SecurityContext; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; import org.glassfish.jersey.server.mvc.Viewable; @@ -33,12 +34,13 @@ import org.glassfish.jersey.server.mvc.Viewable; public class MetricsResources { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MetricsResources.class); + @Inject UserAuthEnabled authEnabled; @Inject SecurityContext sc; @GET @Produces(MediaType.TEXT_HTML) public Viewable getMetrics() { - return ViewableWithPermissions.create("/rest/metrics/metrics.ftl", sc); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/metrics/metrics.ftl", sc); } } http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java index c7f450e..433efaf 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java @@ -34,7 +34,9 @@ import javax.ws.rs.core.SecurityContext; import com.google.common.base.CharMatcher; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import org.apache.drill.exec.client.DrillClient; import org.apache.drill.exec.memory.BufferAllocator; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; import org.apache.drill.exec.work.WorkManager; import org.glassfish.jersey.server.mvc.Viewable; @@ -44,6 +46,7 @@ import org.glassfish.jersey.server.mvc.Viewable; public class QueryResources { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(QueryResources.class); + @Inject UserAuthEnabled authEnabled; @Inject WorkManager work; @Inject SecurityContext sc; @Inject DrillUserPrincipal principal; @@ -52,7 +55,7 @@ public class QueryResources { @Path("/query") @Produces(MediaType.TEXT_HTML) public Viewable getQuery() { - return ViewableWithPermissions.create("/rest/query/query.ftl", sc); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/query/query.ftl", sc); } @POST @@ -60,8 +63,15 @@ public class QueryResources { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public QueryWrapper.QueryResult submitQueryJSON(QueryWrapper query) throws Exception { - final BufferAllocator allocator = work.getContext().getAllocator(); - return query.run(principal.getDrillClient(), allocator); + DrillClient drillClient = null; + + try { + final BufferAllocator allocator = work.getContext().getAllocator(); + drillClient = principal.getDrillClient(); + return query.run(drillClient, allocator); + } finally { + principal.recycleDrillClient(drillClient); + } } @POST @@ -72,10 +82,10 @@ public class QueryResources { try { final String trimmedQueryString = CharMatcher.is(';').trimTrailingFrom(query.trim()); final QueryWrapper.QueryResult result = submitQueryJSON(new QueryWrapper(trimmedQueryString, queryType)); - return ViewableWithPermissions.create("/rest/query/result.ftl", sc, new TabularResult(result)); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/query/result.ftl", sc, new TabularResult(result)); } catch(Exception | Error e) { logger.error("Query from Web UI Failed", e); - return ViewableWithPermissions.create("/rest/query/errorMessage.ftl", sc, e); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/query/errorMessage.ftl", sc, e); } } http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java index 05eed49..439cb7f 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StatusResources.java @@ -35,6 +35,7 @@ import javax.xml.bind.annotation.XmlRootElement; import org.apache.drill.exec.server.options.OptionValue; import org.apache.drill.exec.server.options.OptionValue.Kind; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; import org.apache.drill.exec.work.WorkManager; import org.glassfish.jersey.server.mvc.Viewable; @@ -47,6 +48,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; public class StatusResources { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(StatusResources.class); + @Inject UserAuthEnabled authEnabled; @Inject WorkManager work; @Inject SecurityContext sc; @@ -54,7 +56,7 @@ public class StatusResources { @Path("/status") @Produces(MediaType.TEXT_HTML) public Viewable getStatus() { - return ViewableWithPermissions.create("/rest/status.ftl", sc, "Running!"); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/status.ftl", sc, "Running!"); } @GET @@ -74,7 +76,7 @@ public class StatusResources { @RolesAllowed(DrillUserPrincipal.AUTHENTICATED_ROLE) @Produces(MediaType.TEXT_HTML) public Viewable getSystemOptions() { - return ViewableWithPermissions.create("/rest/options.ftl", sc, getSystemOptionsJSON()); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/options.ftl", sc, getSystemOptionsJSON()); } @POST http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java index 3266eda..ce26a31 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/StorageResources.java @@ -40,6 +40,7 @@ import javax.xml.bind.annotation.XmlRootElement; import org.apache.drill.common.exceptions.ExecutionSetupException; import org.apache.drill.common.logical.StoragePluginConfig; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.store.StoragePlugin; import org.apache.drill.exec.store.StoragePluginRegistry; import org.glassfish.jersey.server.mvc.Viewable; @@ -56,6 +57,7 @@ import static org.apache.drill.exec.server.rest.auth.DrillUserPrincipal.ADMIN_RO public class StorageResources { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(StorageResources.class); + @Inject UserAuthEnabled authEnabled; @Inject StoragePluginRegistry storage; @Inject ObjectMapper mapper; @Inject SecurityContext sc; @@ -88,7 +90,7 @@ public class StorageResources { @Produces(MediaType.TEXT_HTML) public Viewable getStoragePlugins() { List<PluginConfigWrapper> list = getStoragePluginsJSON(); - return ViewableWithPermissions.create("/rest/storage/list.ftl", sc, list); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/storage/list.ftl", sc, list); } @GET @@ -111,7 +113,7 @@ public class StorageResources { @Produces(MediaType.TEXT_HTML) public Viewable getStoragePlugin(@PathParam("name") String name) { PluginConfigWrapper plugin = getStoragePluginJSON(name); - return ViewableWithPermissions.create("/rest/storage/update.ftl", sc, plugin); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/storage/update.ftl", sc, plugin); } @GET http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ThreadsResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ThreadsResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ThreadsResources.java index ae2e3a0..08f22d8 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ThreadsResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ThreadsResources.java @@ -25,6 +25,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.SecurityContext; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; import org.glassfish.jersey.server.mvc.Viewable; @@ -33,12 +34,13 @@ import org.glassfish.jersey.server.mvc.Viewable; public class ThreadsResources { static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MetricsResources.class); + @Inject UserAuthEnabled authEnabled; @Inject SecurityContext sc; @GET @Produces(MediaType.TEXT_HTML) public Viewable getMetrics() { - return ViewableWithPermissions.create("/rest/threads/threads.ftl", sc); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/threads/threads.ftl", sc); } } http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ViewableWithPermissions.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ViewableWithPermissions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ViewableWithPermissions.java index 7e20e5c..b2a0fae 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ViewableWithPermissions.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/ViewableWithPermissions.java @@ -18,7 +18,6 @@ package org.apache.drill.exec.server.rest; import com.google.common.collect.ImmutableMap; -import org.apache.drill.exec.server.rest.auth.AnonymousAuthenticator; import org.apache.drill.exec.server.rest.auth.AuthDynamicFeature; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; import org.glassfish.jersey.server.mvc.Viewable; @@ -37,8 +36,8 @@ public class ViewableWithPermissions extends Viewable { * @param sc * @return */ - public static Viewable create(final String templateName, final SecurityContext sc) { - return new ViewableWithPermissions(templateName, sc, true, null); + public static Viewable create(final boolean authEnabled, final String templateName, final SecurityContext sc) { + return new ViewableWithPermissions(authEnabled, templateName, sc, true, null); } /** @@ -48,8 +47,9 @@ public class ViewableWithPermissions extends Viewable { * @param model * @return */ - public static Viewable create(final String templateName, final SecurityContext sc, final Object model) { - return new ViewableWithPermissions(templateName, sc, true, model); + public static Viewable create(final boolean authEnabled, final String templateName, final SecurityContext sc, + final Object model) { + return new ViewableWithPermissions(authEnabled, templateName, sc, true, model); } /** @@ -58,17 +58,19 @@ public class ViewableWithPermissions extends Viewable { * @return */ public static Viewable createLoginPage(final String errorMsg) { - return new ViewableWithPermissions("/rest/login.ftl", null, false, errorMsg); + return new ViewableWithPermissions(true, "/rest/login.ftl", null, false, errorMsg); } - private ViewableWithPermissions(final String templateName, final SecurityContext sc, final boolean showControls, - final Object model) throws IllegalArgumentException { - super(templateName, createModel(sc, showControls, model)); + private ViewableWithPermissions(final boolean authEnabled, final String templateName, final SecurityContext sc, + final boolean showControls, final Object model) throws IllegalArgumentException { + super(templateName, createModel(authEnabled, sc, showControls, model)); } - private static Map<String, Object> createModel(final SecurityContext sc, final boolean showControls, - final Object pageModel) { - final boolean isAdmin = showControls && sc.isUserInRole(DrillUserPrincipal.ADMIN_ROLE); + private static Map<String, Object> createModel(final boolean authEnabled, final SecurityContext sc, + final boolean showControls, final Object pageModel) { + + final boolean isAdmin = !authEnabled /* when auth is disabled every user is an admin user */ + || (showControls && sc.isUserInRole(DrillUserPrincipal.ADMIN_ROLE)); final boolean isUserLoggedIn = AuthDynamicFeature.isUserLoggedIn(sc); @@ -76,10 +78,10 @@ public class ViewableWithPermissions extends Viewable { .put("showStorage", isAdmin) .put("showOptions", isAdmin) .put("showThreads", isAdmin) - .put("showLogin", showControls && !isUserLoggedIn) - .put("showLogout", showControls && isUserLoggedIn && - !AnonymousAuthenticator.METHOD.equals(sc.getAuthenticationScheme())) - .put("loggedInUserName", showControls && isUserLoggedIn ? sc.getUserPrincipal().getName() : "anonymous") + .put("showLogin", authEnabled && showControls && !isUserLoggedIn) + .put("showLogout", authEnabled && showControls && isUserLoggedIn) + .put("loggedInUserName", authEnabled && showControls && + isUserLoggedIn ? sc.getUserPrincipal().getName() : DrillUserPrincipal.ANONYMOUS_USER) .put("showControls", showControls); if (pageModel != null) { http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java index 6519169..b4e25cb 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java @@ -25,9 +25,6 @@ import com.google.common.collect.ImmutableSet; import org.apache.commons.lang3.RandomStringUtils; import org.apache.drill.common.config.DrillConfig; import org.apache.drill.exec.ExecConstants; -import org.apache.drill.exec.server.DrillbitContext; -import org.apache.drill.exec.server.rest.auth.AnonymousAuthenticator; -import org.apache.drill.exec.server.rest.auth.AnonymousLoginService; import org.apache.drill.exec.server.rest.auth.DrillRestLoginService; import org.apache.drill.exec.work.WorkManager; import org.bouncycastle.asn1.x500.X500NameBuilder; @@ -149,8 +146,10 @@ public class WebServer implements AutoCloseable { staticHolder.setInitParameter("pathInfoOnly", "true"); servletContextHandler.addServlet(staticHolder, "/static/*"); - servletContextHandler.setSecurityHandler(createSecurityHandler()); - servletContextHandler.setSessionHandler(createSessionHandler(servletContextHandler.getSecurityHandler())); + if (config.getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED)) { + servletContextHandler.setSecurityHandler(createSecurityHandler()); + servletContextHandler.setSessionHandler(createSessionHandler(servletContextHandler.getSecurityHandler())); + } embeddedJetty.start(); } @@ -190,25 +189,13 @@ public class WebServer implements AutoCloseable { * @return {@link SecurityHandler} with appropriate {@link LoginService}, {@link Authenticator} and constraints. */ private ConstraintSecurityHandler createSecurityHandler() { - final LoginService loginService; - final Authenticator authenticator; - - final DrillbitContext drillbitContext = workManager.getContext(); - if (config.getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED)) { - loginService = new DrillRestLoginService(drillbitContext); - authenticator = new FormAuthenticator("/login", "/login", true); - } else { - loginService = new AnonymousLoginService(drillbitContext); - authenticator = new AnonymousAuthenticator(); - } - ConstraintSecurityHandler security = new ConstraintSecurityHandler(); Set<String> knownRoles = ImmutableSet.of(AUTHENTICATED_ROLE, ADMIN_ROLE); security.setConstraintMappings(Collections.<ConstraintMapping>emptyList(), knownRoles); - security.setAuthenticator(authenticator); - security.setLoginService(loginService); + security.setAuthenticator(new FormAuthenticator("/login", "/login", true)); + security.setLoginService(new DrillRestLoginService(workManager.getContext())); return security; } http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousAuthenticator.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousAuthenticator.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousAuthenticator.java deleted file mode 100644 index ff796e2..0000000 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousAuthenticator.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.drill.exec.server.rest.auth; - -import org.eclipse.jetty.security.Authenticator; -import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.ServerAuthException; -import org.eclipse.jetty.security.authentication.FormAuthenticator; -import org.eclipse.jetty.security.authentication.SessionAuthentication; -import org.eclipse.jetty.server.Authentication; -import org.eclipse.jetty.server.Authentication.User; - -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -/** - * Equivalent to {@link FormAuthenticator} used when user authentication is disabled. Purpose is to make sure - * a session is established even if the user is "anonymous". - */ -public class AnonymousAuthenticator implements Authenticator { - public static final String METHOD = "ANONYMOUS"; - - private LoginService loginService; - - @Override - public void setConfiguration(AuthConfiguration configuration) { - loginService = configuration.getLoginService(); - } - - @Override - public String getAuthMethod() { - return METHOD; - } - - @Override - public void prepareRequest(ServletRequest request) { - // No-op - } - - @Override - public Authentication validateRequest(ServletRequest req, ServletResponse resp, boolean mandatory) - throws ServerAuthException { - final HttpServletRequest request = (HttpServletRequest)req; - - // Create a session if one not exists already - final HttpSession session = request.getSession(true); - - if (session.getAttribute(SessionAuthentication.__J_AUTHENTICATED) != null) { - // If the session already been authenticated, return the stored auth details - return (SessionAuthentication) session.getAttribute(SessionAuthentication.__J_AUTHENTICATED); - } - - // Create a new session authentication and set it in session. - final SessionAuthentication sessionAuth = new SessionAuthentication(getAuthMethod(), - loginService.login(null, null), null); - - session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, sessionAuth); - - return sessionAuth; - } - - @Override - public boolean secureResponse(ServletRequest req, ServletResponse resp, boolean mandatory, - User validatedUser) throws ServerAuthException { - return true; - } -} http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousLoginService.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousLoginService.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousLoginService.java deleted file mode 100644 index f6cae51..0000000 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/AnonymousLoginService.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.drill.exec.server.rest.auth; - -import org.apache.drill.common.AutoCloseables; -import org.apache.drill.exec.client.DrillClient; -import org.apache.drill.exec.server.DrillbitContext; -import org.eclipse.jetty.server.UserIdentity; - -import javax.security.auth.Subject; - -/** - * LoginService used when user authentication is disabled. This allows all users and establishes a session for each - * "anonymous" user. - */ -public class AnonymousLoginService extends AbstractDrillLoginService { - private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AnonymousLoginService.class); - - public AnonymousLoginService(DrillbitContext drillbitContext) { - super(drillbitContext); - } - - @Override - public String getName() { - return "AnonymousLoginService"; - } - - @Override - public UserIdentity login(String userName, Object credentials) { - DrillClient client = null; - try { - client = createDrillClient(DrillUserPrincipal.ANONYMOUS_USER, null); - final DrillUserPrincipal principal = new DrillUserPrincipal(DrillUserPrincipal.ANONYMOUS_USER, - true /* all users are admins when auth is disabled */, client); - final Subject subject = new Subject(); - subject.getPrincipals().add(principal); - subject.getPrivateCredentials().add(credentials); - - subject.getPrincipals().addAll(DrillUserPrincipal.ADMIN_PRINCIPALS); - return identityService.newUserIdentity(subject, principal, DrillUserPrincipal.ADMIN_USER_ROLES); - } catch (final Exception e) { - AutoCloseables.close(e, client); - logger.error("Login failed.", e); - return null; - } - } -} http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillUserPrincipal.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillUserPrincipal.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillUserPrincipal.java index 16e6f38..18539ff 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillUserPrincipal.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/auth/DrillUserPrincipal.java @@ -18,9 +18,12 @@ package org.apache.drill.exec.server.rest.auth; import com.google.common.collect.ImmutableList; +import org.apache.drill.common.AutoCloseables; import org.apache.drill.exec.client.DrillClient; +import org.apache.drill.exec.server.DrillbitContext; import org.eclipse.jetty.security.MappedLoginService.RolePrincipal; +import java.io.IOException; import java.security.Principal; import java.util.List; @@ -43,9 +46,10 @@ public class DrillUserPrincipal implements Principal, AutoCloseable { public static final List<RolePrincipal> NON_ADMIN_PRINCIPALS = ImmutableList.of(new RolePrincipal(AUTHENTICATED_ROLE)); + protected DrillClient drillClient; + private final String userName; private final boolean isAdmin; - private DrillClient drillClient; public DrillUserPrincipal(final String userName, final boolean isAdmin, final DrillClient drillClient) { this.userName = userName; @@ -59,13 +63,21 @@ public class DrillUserPrincipal implements Principal, AutoCloseable { } /** - * @return Return {@link DrillClient} instanced with credentials of this user principal. + * @return Return {@link DrillClient} instanced with credentials of this user principal. Returned {@link DrillClient} + * must be returned using {@link #recycleDrillClient(DrillClient)} for proper resource cleanup. */ - public DrillClient getDrillClient() { + public DrillClient getDrillClient() throws IOException { return drillClient; } /** + * Return {@link DrillClient} returned from {@link #getDrillClient()} for proper resource cleanup or reuse. + */ + public void recycleDrillClient(final DrillClient client) throws IOException { + // default is no-op. we reuse DrillClient + } + + /** * Is the user identified by this user principal can manage (read) the profile owned by the given user? * @param profileOwner Owner of the profile. * @return @@ -90,4 +102,35 @@ public class DrillUserPrincipal implements Principal, AutoCloseable { drillClient = null; // Reset it to null to avoid closing multiple times. } } + + /** + * {@link DrillUserPrincipal} for anonymous (auth disabled) mode. + */ + public static class AnonDrillUserPrincipal extends DrillUserPrincipal { + private final DrillbitContext drillbitContext; + + public AnonDrillUserPrincipal(final DrillbitContext drillbitContext) { + super(ANONYMOUS_USER, true /* in anonymous (auth disabled) mode all users are admins */, null); + this.drillbitContext = drillbitContext; + } + + @Override + public DrillClient getDrillClient() throws IOException { + try { + // Create a DrillClient + drillClient = new DrillClient(drillbitContext.getConfig(), + drillbitContext.getClusterCoordinator(), drillbitContext.getAllocator()); + drillClient.connect(); + return drillClient; + } catch (final Exception e) { + AutoCloseables.close(e, drillClient); + throw new IOException("Failed to create DrillClient: " + e.getMessage(), e); + } + } + + @Override + public void recycleDrillClient(DrillClient client) throws IOException { + drillClient.close(); + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/drill/blob/c98edbaf/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java index ddc9da1..05441c0 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java @@ -44,6 +44,7 @@ import org.apache.drill.exec.proto.UserBitShared.QueryId; import org.apache.drill.exec.proto.UserBitShared.QueryInfo; import org.apache.drill.exec.proto.UserBitShared.QueryProfile; import org.apache.drill.exec.proto.helper.QueryIdHelper; +import org.apache.drill.exec.server.rest.DrillRestServer.UserAuthEnabled; import org.apache.drill.exec.server.rest.ViewableWithPermissions; import org.apache.drill.exec.server.rest.auth.DrillUserPrincipal; import org.apache.drill.exec.store.sys.PersistentStore; @@ -62,6 +63,7 @@ public class ProfileResources { public final static int MAX_PROFILES = 100; + @Inject UserAuthEnabled authEnabled; @Inject WorkManager work; @Inject DrillUserPrincipal principal; @Inject SecurityContext sc; @@ -192,7 +194,7 @@ public class ProfileResources { @Produces(MediaType.TEXT_HTML) public Viewable getProfiles() { QProfiles profiles = getProfilesJSON(); - return ViewableWithPermissions.create("/rest/profile/list.ftl", sc, profiles); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/profile/list.ftl", sc, profiles); } private QueryProfile getQueryProfile(String queryId) { @@ -258,7 +260,7 @@ public class ProfileResources { @Produces(MediaType.TEXT_HTML) public Viewable getProfile(@PathParam("queryid") String queryId){ ProfileWrapper wrapper = new ProfileWrapper(getQueryProfile(queryId)); - return ViewableWithPermissions.create("/rest/profile/profile.ftl", sc, wrapper); + return ViewableWithPermissions.create(authEnabled.get(), "/rest/profile/profile.ftl", sc, wrapper); }
