From c0855dbc2540c1826a0c88ccfd6d764cfbda615f Mon Sep 17 00:00:00 2001 From: jon-wei Date: Thu, 9 Nov 2017 19:15:53 -0800 Subject: [PATCH 1/2] Split internal client escalation from Authenticator interface --- .../druid/benchmark/query/SqlBenchmark.java | 3 +- docs/content/configuration/auth.md | 22 +-- .../kerberos/DruidKerberosModule.java | 3 +- .../kerberos/KerberosAuthenticator.java | 84 ----------- .../security/kerberos/KerberosEscalator.java | 134 ++++++++++++++++++ .../sql/QuantileSqlAggregatorTest.java | 3 +- .../io/druid/guice/http/HttpClientModule.java | 11 +- .../guice/security/AuthenticatorModule.java | 2 +- .../guice/security/AuthorizerModule.java | 2 +- .../druid/guice/security/EscalatorModule.java | 34 +++++ .../druid/initialization/Initialization.java | 6 +- .../server/AsyncQueryForwardingServlet.java | 11 +- .../AuthenticatorHttpClientWrapperModule.java | 69 --------- .../AuthenticatorMapperModule.java | 48 ++++++- .../AuthorizerMapperModule.java | 27 +++- .../security/AllowAllAuthenticator.java | 20 --- ...entWrapper.java => AllowAllEscalator.java} | 24 ++-- .../druid/server/security/AuthTestUtils.java | 2 +- .../druid/server/security/Authenticator.java | 35 ----- .../server/security/AuthenticatorMapper.java | 16 +-- .../io/druid/server/security/Escalator.java | 65 +++++++++ .../AsyncQueryForwardingServletTest.java | 4 +- .../io/druid/sql/avatica/DruidStatement.java | 2 +- .../sql/calcite/planner/DruidPlanner.java | 14 +- .../sql/calcite/planner/PlannerFactory.java | 11 +- .../druid/sql/calcite/schema/DruidSchema.java | 13 +- .../sql/avatica/DruidAvaticaHandlerTest.java | 7 +- .../druid/sql/avatica/DruidStatementTest.java | 3 +- .../druid/sql/calcite/CalciteQueryTest.java | 2 +- .../sql/calcite/http/SqlResourceTest.java | 3 +- .../sql/calcite/schema/DruidSchemaTest.java | 4 +- .../druid/sql/calcite/util/CalciteTests.java | 25 ++-- 32 files changed, 394 insertions(+), 315 deletions(-) create mode 100644 extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosEscalator.java create mode 100644 server/src/main/java/io/druid/guice/security/EscalatorModule.java delete mode 100644 server/src/main/java/io/druid/server/initialization/AuthenticatorHttpClientWrapperModule.java rename server/src/main/java/io/druid/server/security/{AuthenticatorHttpClientWrapper.java => AllowAllEscalator.java} (63%) create mode 100644 server/src/main/java/io/druid/server/security/Escalator.java diff --git a/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java b/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java index 8433a6b0d65e..ab88b08947d3 100644 --- a/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java +++ b/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java @@ -39,6 +39,7 @@ import io.druid.query.dimension.DimensionSpec; import io.druid.query.groupby.GroupByQuery; import io.druid.segment.QueryableIndex; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.planner.DruidPlanner; @@ -120,8 +121,8 @@ public void setup() throws Exception CalciteTests.createExprMacroTable(), plannerConfig, new AuthConfig(), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER, AuthTestUtils.TEST_AUTHORIZER_MAPPER, + new AllowAllEscalator(), CalciteTests.getJsonMapper() ); groupByQuery = GroupByQuery diff --git a/docs/content/configuration/auth.md b/docs/content/configuration/auth.md index 254bfb8221f9..8f1fe18de6eb 100644 --- a/docs/content/configuration/auth.md +++ b/docs/content/configuration/auth.md @@ -7,7 +7,7 @@ layout: doc_page |Property|Type|Description|Default|Required| |--------|-----------|--------|--------|--------| |`druid.auth.authenticationChain`|JSON List of Strings|List of Authenticator type names|["allowAll"]|no| -|`druid.auth.escalatedAuthenticator`|String|Type of the Authenticator that should be used for internal Druid communications. This Authenticator must be present in `druid.auth.authenticationChain`.|"allowAll"|no| +|`druid.escalator.type`|String|Type of the Escalator that should be used for internal Druid communications. This Escalator must have the same type as an Authenticator in `druid.auth.authenticationChain`.|"allowAll"|no| |`druid.auth.authorizers`|JSON List of Strings|List of Authorizer type names |["allowAll"]|no| ## Enabling Authentication/Authorization @@ -33,10 +33,14 @@ Druid includes a built-in Authenticator, used for the default unsecured configur This built-in Authenticator authenticates all requests, and always directs them to an Authorizer named "allowAll". It is not intended to be used for anything other than the default unsecured configuration. -## Internal Authenticator -The `druid.auth.escalatedAuthenticator` property determines what authentication scheme should be used for internal Druid cluster communications (such as when a broker node communicates with historical nodes for query processing). +## Escalator +The `druid.escalator.type` property determines what authentication scheme should be used for internal Druid cluster communications (such as when a broker node communicates with historical nodes for query processing). -The Authenticator chosen for this property must also be present in `druid.auth.authenticationChain`. +The Escalator chosen for this property must have the same type as an Authenticator in `druid.auth.authenticationChain. Authenticator extension implementors must also provide a corresponding Escalator implementation with the same type name if they intend to use a particular authentication scheme for internal Druid communications. + +### AllowAll Escalator + +This built-in default Escalator is intended for use only with the default AllowAll Authenticator and Authorizer. ## Authorizers Authorization decisions are handled by an Authorizer. The `druid.auth.authorizers` property determines what Authorizer implementations will be active. @@ -63,7 +67,7 @@ When `druid.auth.authenticationChain` is left empty or unspecified, Druid will c When `druid.auth.authorizers` is left empty or unspecified, Druid will create a single AllowAll Authorizer named "allowAll". -The default value of `druid.auth.escalatedAuthenticator` is "allowAll" to match the default unsecured Authenticator/Authorizer configurations. +The default value of `druid.escalator.type` is "allowAll" to match the default unsecured Authenticator/Authorizer configurations. ## Authenticator to Authorizer Routing @@ -77,15 +81,17 @@ Internal requests between Druid nodes (non-user initiated communications) need t These requests should be run as an "internal system user", an identity that represents the Druid cluster itself, with full access permissions. -The details of how the internal system user is defined is left to Authorizer and Authenticator implementations. +The details of how the internal system user is defined is left to extension implementations. ### Authorizer Internal System User Handling Authorizers implementations must recognize and authorize an identity for the "internal system user", with full access permissions. -### Authenticator Internal System User Handling +### Authenticator and Escalator Internal System User Handling + +An Authenticator implementation that is intended to support internal Druid communications must recognize credentials for the "internal system user", as provided by a corresponding Escalator implementation. -Authenticators must implement three methods related to the internal system user: +An Escalator must implement three methods related to the internal system user: ```java public HttpClient createEscalatedClient(HttpClient baseClient); diff --git a/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/DruidKerberosModule.java b/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/DruidKerberosModule.java index e4058bc92d52..7685a0c7cb45 100644 --- a/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/DruidKerberosModule.java +++ b/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/DruidKerberosModule.java @@ -37,7 +37,8 @@ public List getJacksonModules() { return ImmutableList.of( new SimpleModule("DruidKerberos").registerSubtypes( - KerberosAuthenticator.class + KerberosAuthenticator.class, + KerberosEscalator.class ) ); } diff --git a/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosAuthenticator.java b/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosAuthenticator.java index 67d698b77334..785a5a415cb5 100644 --- a/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosAuthenticator.java +++ b/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosAuthenticator.java @@ -24,7 +24,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; import com.google.common.base.Throwables; -import com.metamx.http.client.HttpClient; import io.druid.guice.annotations.Self; import io.druid.java.util.common.StringUtils; import io.druid.java.util.common.logger.Logger; @@ -34,7 +33,6 @@ import io.druid.server.security.Authenticator; import org.apache.commons.codec.binary.Base64; import org.apache.hadoop.security.SecurityUtil; -import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authentication.client.AuthenticatedURL; import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.security.authentication.server.AuthenticationFilter; @@ -43,11 +41,6 @@ import org.apache.hadoop.security.authentication.util.Signer; import org.apache.hadoop.security.authentication.util.SignerException; import org.apache.hadoop.security.authentication.util.SignerSecretProvider; -import org.eclipse.jetty.client.api.Authentication; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.util.Attributes; -import org.jboss.netty.handler.codec.http.HttpHeaders; import sun.security.krb5.EncryptedData; import sun.security.krb5.EncryptionKey; import sun.security.krb5.internal.APReq; @@ -79,9 +72,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; -import java.net.URI; import java.security.Principal; -import java.security.PrivilegedExceptionAction; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -112,7 +103,6 @@ public class KerberosAuthenticator implements Authenticator private final String authorizerName; private LoginContext loginContext; - @JsonCreator public KerberosAuthenticator( @JsonProperty("serverPrincipal") String serverPrincipal, @@ -440,80 +430,6 @@ public AuthenticationResult authenticateJDBCContext(Map context) throw new UnsupportedOperationException("JDBC Kerberos auth not supported yet"); } - @Override - public HttpClient createEscalatedClient(HttpClient baseClient) - { - return new KerberosHttpClient(baseClient, internalClientPrincipal, internalClientKeytab); - } - - @Override - public org.eclipse.jetty.client.HttpClient createEscalatedJettyClient(org.eclipse.jetty.client.HttpClient baseClient) - { - baseClient.getAuthenticationStore().addAuthentication(new Authentication() - { - @Override - public boolean matches(String type, URI uri, String realm) - { - return true; - } - - @Override - public Result authenticate( - final Request request, ContentResponse response, Authentication.HeaderInfo headerInfo, Attributes context - ) - { - return new Result() - { - @Override - public URI getURI() - { - return request.getURI(); - } - - @Override - public void apply(Request request) - { - try { - // No need to set cookies as they are handled by Jetty Http Client itself. - URI uri = request.getURI(); - if (DruidKerberosUtil.needToSendCredentials(baseClient.getCookieStore(), uri)) { - log.debug( - "No Auth Cookie found for URI[%s]. Existing Cookies[%s] Authenticating... ", - uri, - baseClient.getCookieStore().getCookies() - ); - final String host = request.getHost(); - DruidKerberosUtil.authenticateIfRequired(internalClientPrincipal, internalClientKeytab); - UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); - String challenge = currentUser.doAs(new PrivilegedExceptionAction() - { - @Override - public String run() throws Exception - { - return DruidKerberosUtil.kerberosChallenge(host); - } - }); - request.getHeaders().add(HttpHeaders.Names.AUTHORIZATION, "Negotiate " + challenge); - } else { - log.debug("Found Auth Cookie found for URI[%s].", uri); - } - } - catch (Throwable e) { - Throwables.propagate(e); - } - } - }; - } - }); - return baseClient; - } - - @Override - public AuthenticationResult createEscalatedAuthenticationResult() - { - return new AuthenticationResult(internalClientPrincipal, authorizerName, null); - } - private boolean isExcluded(String path) { for (String excluded : excludedPaths) { diff --git a/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosEscalator.java b/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosEscalator.java new file mode 100644 index 000000000000..e995233a23c2 --- /dev/null +++ b/extensions-core/druid-kerberos/src/main/java/io/druid/security/kerberos/KerberosEscalator.java @@ -0,0 +1,134 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets 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 io.druid.security.kerberos; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.google.common.base.Throwables; +import com.metamx.http.client.HttpClient; +import io.druid.java.util.common.logger.Logger; +import io.druid.server.security.AuthenticationResult; +import io.druid.server.security.Escalator; +import org.apache.hadoop.security.UserGroupInformation; +import org.eclipse.jetty.client.api.Authentication; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.util.Attributes; +import org.jboss.netty.handler.codec.http.HttpHeaders; + +import java.net.URI; +import java.security.PrivilegedExceptionAction; + +@JsonTypeName("kerberos") +public class KerberosEscalator implements Escalator +{ + private static final Logger log = new Logger(KerberosAuthenticator.class); + + private final String internalClientPrincipal; + private final String internalClientKeytab; + private final String authorizerName; + + @JsonCreator + public KerberosEscalator( + @JsonProperty("authorizerName") String authorizerName, + @JsonProperty("internalClientPrincipal") String internalClientPrincipal, + @JsonProperty("internalClientKeytab") String internalClientKeytab + ) + { + this.authorizerName = authorizerName; + this.internalClientPrincipal = internalClientPrincipal; + this.internalClientKeytab = internalClientKeytab; + + } + @Override + public HttpClient createEscalatedClient(HttpClient baseClient) + { + return new KerberosHttpClient(baseClient, internalClientPrincipal, internalClientKeytab); + } + + @Override + public org.eclipse.jetty.client.HttpClient createEscalatedJettyClient(org.eclipse.jetty.client.HttpClient baseClient) + { + baseClient.getAuthenticationStore().addAuthentication(new Authentication() + { + @Override + public boolean matches(String type, URI uri, String realm) + { + return true; + } + + @Override + public Result authenticate( + final Request request, ContentResponse response, Authentication.HeaderInfo headerInfo, Attributes context + ) + { + return new Result() + { + @Override + public URI getURI() + { + return request.getURI(); + } + + @Override + public void apply(Request request) + { + try { + // No need to set cookies as they are handled by Jetty Http Client itself. + URI uri = request.getURI(); + if (DruidKerberosUtil.needToSendCredentials(baseClient.getCookieStore(), uri)) { + log.debug( + "No Auth Cookie found for URI[%s]. Existing Cookies[%s] Authenticating... ", + uri, + baseClient.getCookieStore().getCookies() + ); + final String host = request.getHost(); + DruidKerberosUtil.authenticateIfRequired(internalClientPrincipal, internalClientKeytab); + UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); + String challenge = currentUser.doAs(new PrivilegedExceptionAction() + { + @Override + public String run() throws Exception + { + return DruidKerberosUtil.kerberosChallenge(host); + } + }); + request.getHeaders().add(HttpHeaders.Names.AUTHORIZATION, "Negotiate " + challenge); + } else { + log.debug("Found Auth Cookie found for URI[%s].", uri); + } + } + catch (Throwable e) { + Throwables.propagate(e); + } + } + }; + } + }); + return baseClient; + } + + @Override + public AuthenticationResult createEscalatedAuthenticationResult() + { + return new AuthenticationResult(internalClientPrincipal, authorizerName, null); + } +} diff --git a/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java b/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java index 9f511b6f3abf..f0b7794427a6 100644 --- a/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java +++ b/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java @@ -43,6 +43,7 @@ import io.druid.segment.column.ValueType; import io.druid.segment.incremental.IncrementalIndexSchema; import io.druid.segment.virtual.ExpressionVirtualColumn; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.filtration.Filtration; @@ -136,8 +137,8 @@ public void setUp() throws Exception CalciteTests.createExprMacroTable(), plannerConfig, new AuthConfig(), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER, AuthTestUtils.TEST_AUTHORIZER_MAPPER, + new AllowAllEscalator(), CalciteTests.getJsonMapper() ); } diff --git a/server/src/main/java/io/druid/guice/http/HttpClientModule.java b/server/src/main/java/io/druid/guice/http/HttpClientModule.java index 848bb9b3eb8f..73b06163c0ce 100644 --- a/server/src/main/java/io/druid/guice/http/HttpClientModule.java +++ b/server/src/main/java/io/druid/guice/http/HttpClientModule.java @@ -32,8 +32,7 @@ import io.druid.guice.annotations.EscalatedGlobal; import io.druid.guice.annotations.Global; import io.druid.java.util.common.StringUtils; -import io.druid.server.security.Authenticator; -import io.druid.server.security.AuthenticatorMapper; +import io.druid.server.security.Escalator; import java.lang.annotation.Annotation; import java.util.Set; @@ -106,7 +105,7 @@ public void configure(Binder binder) public static class HttpClientProvider extends AbstractHttpClientProvider { private boolean isEscalated; - private Authenticator escalatingAuthenticator; + private Escalator escalator; public HttpClientProvider(boolean isEscalated) { @@ -126,9 +125,9 @@ public HttpClientProvider(Class annotationClazz, boolean i } @Inject - public void inject(AuthenticatorMapper authenticatorMapper) + public void inject(Escalator escalator) { - this.escalatingAuthenticator = authenticatorMapper.getEscalatingAuthenticator(); + this.escalator = escalator; } @Override @@ -155,7 +154,7 @@ public HttpClient get() ); if (isEscalated) { - return escalatingAuthenticator.createEscalatedClient(client); + return escalator.createEscalatedClient(client); } else { return client; } diff --git a/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java b/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java index 7c09284ef52f..5ae6015c8b07 100644 --- a/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java +++ b/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java @@ -27,8 +27,8 @@ import com.google.inject.name.Named; import io.druid.guice.LazySingleton; import io.druid.guice.PolyBind; -import io.druid.server.security.Authenticator; import io.druid.server.security.AllowAllAuthenticator; +import io.druid.server.security.Authenticator; public class AuthenticatorModule implements Module { diff --git a/server/src/main/java/io/druid/guice/security/AuthorizerModule.java b/server/src/main/java/io/druid/guice/security/AuthorizerModule.java index a39a3dc09462..a27286a9a0e2 100644 --- a/server/src/main/java/io/druid/guice/security/AuthorizerModule.java +++ b/server/src/main/java/io/druid/guice/security/AuthorizerModule.java @@ -27,8 +27,8 @@ import com.google.inject.name.Named; import io.druid.guice.LazySingleton; import io.druid.guice.PolyBind; -import io.druid.server.security.Authorizer; import io.druid.server.security.AllowAllAuthorizer; +import io.druid.server.security.Authorizer; public class AuthorizerModule implements Module { diff --git a/server/src/main/java/io/druid/guice/security/EscalatorModule.java b/server/src/main/java/io/druid/guice/security/EscalatorModule.java new file mode 100644 index 000000000000..7e0b719966b0 --- /dev/null +++ b/server/src/main/java/io/druid/guice/security/EscalatorModule.java @@ -0,0 +1,34 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets 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 io.druid.guice.security; + +import com.google.inject.Binder; +import com.google.inject.Module; +import io.druid.guice.JsonConfigProvider; +import io.druid.server.security.Escalator; + +public class EscalatorModule implements Module +{ + @Override + public void configure(Binder binder) + { + JsonConfigProvider.bind(binder, "druid.escalator", Escalator.class); + } +} diff --git a/server/src/main/java/io/druid/initialization/Initialization.java b/server/src/main/java/io/druid/initialization/Initialization.java index a6ab2a0d155c..81ef5e2fdc31 100644 --- a/server/src/main/java/io/druid/initialization/Initialization.java +++ b/server/src/main/java/io/druid/initialization/Initialization.java @@ -60,13 +60,13 @@ import io.druid.guice.security.AuthenticatorModule; import io.druid.guice.security.AuthorizerModule; import io.druid.guice.security.DruidAuthModule; +import io.druid.guice.security.EscalatorModule; import io.druid.java.util.common.ISE; import io.druid.java.util.common.logger.Logger; import io.druid.metadata.storage.derby.DerbyMetadataStorageDruidModule; -import io.druid.server.initialization.AuthenticatorHttpClientWrapperModule; +import io.druid.server.emitter.EmitterModule; import io.druid.server.initialization.AuthenticatorMapperModule; import io.druid.server.initialization.AuthorizerMapperModule; -import io.druid.server.emitter.EmitterModule; import io.druid.server.initialization.jetty.JettyServerModule; import io.druid.server.metrics.MetricsModule; import org.apache.commons.io.FileUtils; @@ -378,7 +378,7 @@ public static Injector makeInjectorWithModules(final Injector baseInjector, Iter new JavaScriptModule(), new AuthenticatorModule(), new AuthenticatorMapperModule(), - new AuthenticatorHttpClientWrapperModule(), + new EscalatorModule(), new AuthorizerModule(), new AuthorizerMapperModule(), new StartupLoggingModule() diff --git a/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java b/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java index d16673660e93..b6c5f287235f 100644 --- a/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java +++ b/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java @@ -44,8 +44,7 @@ import io.druid.server.router.QueryHostFinder; import io.druid.server.router.Router; import io.druid.server.security.AuthConfig; -import io.druid.server.security.Authenticator; -import io.druid.server.security.AuthenticatorMapper; +import io.druid.server.security.Escalator; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; @@ -114,7 +113,7 @@ private static void handleException(HttpServletResponse response, ObjectMapper o private final ServiceEmitter emitter; private final RequestLogger requestLogger; private final GenericQueryMetricsFactory queryMetricsFactory; - private final Authenticator escalatingAuthenticator; + private final Escalator escalator; private HttpClient broadcastClient; @@ -129,7 +128,7 @@ public AsyncQueryForwardingServlet( ServiceEmitter emitter, RequestLogger requestLogger, GenericQueryMetricsFactory queryMetricsFactory, - AuthenticatorMapper authenticatorMapper + Escalator escalator ) { this.warehouse = warehouse; @@ -141,7 +140,7 @@ public AsyncQueryForwardingServlet( this.emitter = emitter; this.requestLogger = requestLogger; this.queryMetricsFactory = queryMetricsFactory; - this.escalatingAuthenticator = authenticatorMapper.getEscalatingAuthenticator(); + this.escalator = escalator; } @Override @@ -349,7 +348,7 @@ protected static URI makeURI(String scheme, String host, String requestURI, Stri @Override protected HttpClient newHttpClient() { - return escalatingAuthenticator.createEscalatedJettyClient(httpClientProvider.get()); + return escalator.createEscalatedJettyClient(httpClientProvider.get()); } @Override diff --git a/server/src/main/java/io/druid/server/initialization/AuthenticatorHttpClientWrapperModule.java b/server/src/main/java/io/druid/server/initialization/AuthenticatorHttpClientWrapperModule.java deleted file mode 100644 index 78f88fe8eb91..000000000000 --- a/server/src/main/java/io/druid/server/initialization/AuthenticatorHttpClientWrapperModule.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to Metamarkets Group Inc. (Metamarkets) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. Metamarkets 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 io.druid.server.initialization; - -import com.fasterxml.jackson.databind.Module; -import com.google.inject.Binder; -import com.google.inject.Inject; -import com.google.inject.Provider; -import io.druid.guice.LazySingleton; -import io.druid.initialization.DruidModule; -import io.druid.java.util.common.logger.Logger; -import io.druid.server.security.AuthenticatorHttpClientWrapper; -import io.druid.server.security.AuthenticatorMapper; - -import java.util.Collections; -import java.util.List; - -public class AuthenticatorHttpClientWrapperModule implements DruidModule -{ - private static Logger log = new Logger(AuthenticatorHttpClientWrapperModule.class); - - @Override - public void configure(Binder binder) - { - binder.bind(AuthenticatorHttpClientWrapper.class) - .toProvider(new AuthenticatorHttpClientWrapperProvider()) - .in(LazySingleton.class); - } - - @Override - public List getJacksonModules() - { - return Collections.EMPTY_LIST; - } - - private static class AuthenticatorHttpClientWrapperProvider implements Provider - { - private AuthenticatorHttpClientWrapper wrapper; - - @Inject - public void inject(AuthenticatorMapper authenticatorMapper) - { - this.wrapper = new AuthenticatorHttpClientWrapper(authenticatorMapper.getEscalatingAuthenticator()); - } - - @Override - public AuthenticatorHttpClientWrapper get() - { - return wrapper; - } - } -} diff --git a/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java b/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java index cb8ccbedfaf7..a8bb321a189f 100644 --- a/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java +++ b/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java @@ -41,9 +41,11 @@ import io.druid.server.security.AllowAllAuthenticator; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; public class AuthenticatorMapperModule implements DruidModule { @@ -91,14 +93,12 @@ public AuthenticatorMapper get() List authenticators = authConfig.getAuthenticatorChain(); + validateProperties(props, authenticators); + // Default configuration is to allow all requests. if (authenticators == null) { authenticatorMap.put("allowAll", new AllowAllAuthenticator()); - return new AuthenticatorMapper(authenticatorMap, "allowAll"); - } - - if (authenticators.isEmpty()) { - throw new IAE("Must have at least one Authenticator configured."); + return new AuthenticatorMapper(authenticatorMap); } for (String authenticatorName : authenticators) { @@ -125,7 +125,43 @@ public AuthenticatorMapper get() authenticatorMap.put(authenticatorName, authenticator); } - return new AuthenticatorMapper(authenticatorMap, authConfig.getEscalatedAuthenticator()); + return new AuthenticatorMapper(authenticatorMap); + } + } + + private static void validateProperties(Properties properties, List authenticators) + { + String escalatorType = properties.getProperty("druid.escalator.type"); + if (escalatorType == null) { + escalatorType = "allowAll"; + } + + if (authenticators == null) { + if (escalatorType.equals("allowAll")) { + return; + } else { + throw new ISE("Using default unsecured configuration with invalid druid.escalator.type [%s]", escalatorType); + } + } + + if (authenticators.isEmpty()) { + throw new IAE("Must have at least one Authenticator configured."); + } + + Set authenticatorSet = new HashSet<>(); + for (String authenticator : authenticators) { + if (authenticatorSet.contains(authenticator)) { + throw new ISE("Cannot have multiple authenticators with the same name: [%s]", authenticator); + } + authenticatorSet.add(authenticator); + } + + for (String authenticator : authenticators) { + String typeProperty = StringUtils.format("druid.auth.authenticator.%s.type", authenticator); + if (escalatorType.equals(properties.getProperty(typeProperty))) { + return; + } } + throw new ISE("druid.escalator.type [%s] does not match any configured authenticator's type!", escalatorType); } } diff --git a/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java b/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java index 6da287a648ea..427a461aa1d4 100644 --- a/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java +++ b/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java @@ -41,9 +41,11 @@ import io.druid.server.security.AuthorizerMapper; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; public class AuthorizerMapperModule implements DruidModule { @@ -89,6 +91,8 @@ public AuthorizerMapper get() Map authorizerMap = Maps.newHashMap(); List authorizers = authConfig.getAuthorizers(); + validateProperties(authorizers); + // Default is allow all if (authorizers == null) { return new AuthorizerMapper(null) { @@ -100,10 +104,6 @@ public Authorizer getAuthorizer(String name) }; } - if (authorizers.isEmpty()) { - throw new IAE("Must have at least one Authorizer configured."); - } - for (String authorizerName : authorizers) { final String authorizerPropertyBase = StringUtils.format(AUTHORIZER_PROPERTIES_FORMAT_STRING, authorizerName); final JsonConfigProvider authorizerProvider = new JsonConfigProvider<>( @@ -132,4 +132,23 @@ public Authorizer getAuthorizer(String name) return new AuthorizerMapper(authorizerMap); } } + + private static void validateProperties(List authorizers) + { + if (authorizers == null) { + return; + } + + if (authorizers.isEmpty()) { + throw new IAE("Must have at least one Authorizer configured."); + } + + Set authorizerSet = new HashSet<>(); + for (String authorizer : authorizers) { + if (authorizerSet.contains(authorizer)) { + throw new ISE("Cannot have multiple authorizers with the same name: [%s]", authorizer); + } + authorizerSet.add(authorizer); + } + } } diff --git a/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java b/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java index cae5a4f01ac6..e525f28045ef 100644 --- a/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java +++ b/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java @@ -19,8 +19,6 @@ package io.druid.server.security; -import com.metamx.http.client.HttpClient; - import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -102,22 +100,4 @@ public AuthenticationResult authenticateJDBCContext(Map context) { return ALLOW_ALL_RESULT; } - - @Override - public HttpClient createEscalatedClient(HttpClient baseClient) - { - return baseClient; - } - - @Override - public org.eclipse.jetty.client.HttpClient createEscalatedJettyClient(org.eclipse.jetty.client.HttpClient baseClient) - { - return baseClient; - } - - @Override - public AuthenticationResult createEscalatedAuthenticationResult() - { - return ALLOW_ALL_RESULT; - } } diff --git a/server/src/main/java/io/druid/server/security/AuthenticatorHttpClientWrapper.java b/server/src/main/java/io/druid/server/security/AllowAllEscalator.java similarity index 63% rename from server/src/main/java/io/druid/server/security/AuthenticatorHttpClientWrapper.java rename to server/src/main/java/io/druid/server/security/AllowAllEscalator.java index 25d4cb7c3d25..737690454550 100644 --- a/server/src/main/java/io/druid/server/security/AuthenticatorHttpClientWrapper.java +++ b/server/src/main/java/io/druid/server/security/AllowAllEscalator.java @@ -21,23 +21,23 @@ import com.metamx.http.client.HttpClient; -/** - * Singleton utility object that creates escalated HttpClients using a configuration-specified Authenticator's - * getEscalatedClient() method. - */ -public class AuthenticatorHttpClientWrapper +public class AllowAllEscalator implements Escalator { - private Authenticator escalatingAuthenticator; + @Override + public HttpClient createEscalatedClient(HttpClient baseClient) + { + return baseClient; + } - public AuthenticatorHttpClientWrapper( - final Authenticator escalatingAuthenticator - ) + @Override + public org.eclipse.jetty.client.HttpClient createEscalatedJettyClient(org.eclipse.jetty.client.HttpClient baseClient) { - this.escalatingAuthenticator = escalatingAuthenticator; + return baseClient; } - public HttpClient getEscalatedClient(HttpClient baseClient) + @Override + public AuthenticationResult createEscalatedAuthenticationResult() { - return escalatingAuthenticator.createEscalatedClient(baseClient); + return AllowAllAuthenticator.ALLOW_ALL_RESULT; } } diff --git a/server/src/main/java/io/druid/server/security/AuthTestUtils.java b/server/src/main/java/io/druid/server/security/AuthTestUtils.java index e06fa9c23030..e07c1b6924f4 100644 --- a/server/src/main/java/io/druid/server/security/AuthTestUtils.java +++ b/server/src/main/java/io/druid/server/security/AuthTestUtils.java @@ -31,7 +31,7 @@ public class AuthTestUtils static { final Map defaultMap = Maps.newHashMap(); defaultMap.put("allowAll", new AllowAllAuthenticator()); - TEST_AUTHENTICATOR_MAPPER = new AuthenticatorMapper(defaultMap, "allowAll"); + TEST_AUTHENTICATOR_MAPPER = new AuthenticatorMapper(defaultMap); TEST_AUTHORIZER_MAPPER = new AuthorizerMapper(null) { @Override diff --git a/server/src/main/java/io/druid/server/security/Authenticator.java b/server/src/main/java/io/druid/server/security/Authenticator.java index d4db90b21733..6525c1b7c15f 100644 --- a/server/src/main/java/io/druid/server/security/Authenticator.java +++ b/server/src/main/java/io/druid/server/security/Authenticator.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.metamx.http.client.HttpClient; import io.druid.server.initialization.jetty.ServletFilterHolder; import javax.annotation.Nullable; @@ -37,10 +36,6 @@ * * - A method that returns a WWW-Authenticate challenge header appropriate for the * authentication mechanism, getAuthChallengeHeader(). - * - A method for creating a wrapped HTTP client that can authenticate using the Authenticator's authentication scheme, - * used for internal Druid node communications (e.g., broker -> historical messages), createEscalatedClient(). - * - A method for creating a wrapped Jetty HTTP client that can authenticate using the Authenticator's authentication scheme, - * used by the Druid router, createEscalatedJettyClient(). * - A method for authenticating credentials contained in a JDBC connection context, used for authenticating Druid SQL * requests received via JDBC, authenticateJDBCContext(). */ @@ -98,34 +93,4 @@ public interface Authenticator extends ServletFilterHolder */ @Nullable AuthenticationResult authenticateJDBCContext(Map context); - - /** - * Return a client that sends requests with the format/information necessary to authenticate successfully - * against this Authenticator's authentication scheme using the identity of the internal system user. - *

- * This HTTP client is used for internal communications between Druid nodes, such as when a broker communicates - * with a historical node during query processing. - * - * @param baseClient Base HTTP client for internal Druid communications - * - * @return metamx HttpClient that sends requests with the credentials of the internal system user - */ - HttpClient createEscalatedClient(HttpClient baseClient); - - /** - * Return a client that sends requests with the format/information necessary to authenticate successfully - * against this Authenticator's authentication scheme using the identity of the internal system user. - *

- * This HTTP client is used by the Druid Router node. - * - * @param baseClient Base Jetty HttpClient - * - * @return Jetty HttpClient that sends requests with the credentials of the internal system user - */ - org.eclipse.jetty.client.HttpClient createEscalatedJettyClient(org.eclipse.jetty.client.HttpClient baseClient); - - /** - * @return an AuthenticationResult representing the identity of the internal system user. - */ - AuthenticationResult createEscalatedAuthenticationResult(); } diff --git a/server/src/main/java/io/druid/server/security/AuthenticatorMapper.java b/server/src/main/java/io/druid/server/security/AuthenticatorMapper.java index 952f607cbaf8..852b7e4a3105 100644 --- a/server/src/main/java/io/druid/server/security/AuthenticatorMapper.java +++ b/server/src/main/java/io/druid/server/security/AuthenticatorMapper.java @@ -19,7 +19,6 @@ package io.druid.server.security; -import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import io.druid.guice.ManageLifecycle; @@ -30,25 +29,12 @@ public class AuthenticatorMapper { private Map authenticatorMap; - private Authenticator escalatingAuthenticator; public AuthenticatorMapper( - Map authenticatorMap, - String escalatingAuthenticatorName + Map authenticatorMap ) { this.authenticatorMap = authenticatorMap; - this.escalatingAuthenticator = authenticatorMap.get(escalatingAuthenticatorName); - Preconditions.checkNotNull( - escalatingAuthenticator, - "Could not find escalating authenticator with name: %s", - escalatingAuthenticatorName - ); - } - - public Authenticator getEscalatingAuthenticator() - { - return escalatingAuthenticator; } public List getAuthenticatorChain() diff --git a/server/src/main/java/io/druid/server/security/Escalator.java b/server/src/main/java/io/druid/server/security/Escalator.java new file mode 100644 index 000000000000..c8fb3279dd52 --- /dev/null +++ b/server/src/main/java/io/druid/server/security/Escalator.java @@ -0,0 +1,65 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets 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 io.druid.server.security; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.metamx.http.client.HttpClient; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = AllowAllEscalator.class) +@JsonSubTypes(value = { + @JsonSubTypes.Type(name = "allowAll", value = AllowAllEscalator.class), +}) +/** + * This interface provides methods needed for escalating internal system requests with priveleged authentication + * credentials. Each Escalator is associated with a specific authentication scheme, like Authenticators. + */ +public interface Escalator +{ + /** + * Return a client that sends requests with the format/information necessary to authenticate successfully + * against this Escalator's authentication scheme using the identity of the internal system user. + *

+ * This HTTP client is used for internal communications between Druid nodes, such as when a broker communicates + * with a historical node during query processing. + * + * @param baseClient Base HTTP client for internal Druid communications + * + * @return metamx HttpClient that sends requests with the credentials of the internal system user + */ + HttpClient createEscalatedClient(HttpClient baseClient); + + /** + * Return a client that sends requests with the format/information necessary to authenticate successfully + * against this Authenticator's authentication scheme using the identity of the internal system user. + *

+ * This HTTP client is used by the Druid Router node. + * + * @param baseClient Base Jetty HttpClient + * + * @return Jetty HttpClient that sends requests with the credentials of the internal system user + */ + org.eclipse.jetty.client.HttpClient createEscalatedJettyClient(org.eclipse.jetty.client.HttpClient baseClient); + + /** + * @return an AuthenticationResult representing the identity of the internal system user. + */ + AuthenticationResult createEscalatedAuthenticationResult(); +} diff --git a/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java b/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java index 329ac6688c8f..23afdc97154f 100644 --- a/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java +++ b/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java @@ -52,7 +52,7 @@ import io.druid.server.router.QueryHostFinder; import io.druid.server.router.RendezvousHashAvaticaConnectionBalancer; import io.druid.server.security.AllowAllAuthorizer; -import io.druid.server.security.AuthTestUtils; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.Authorizer; import io.druid.server.security.AuthorizerMapper; import org.eclipse.jetty.client.HttpClient; @@ -253,7 +253,7 @@ public void log(RequestLogLine requestLogLine) throws IOException } }, new DefaultGenericQueryMetricsFactory(jsonMapper), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER + new AllowAllEscalator() ) { @Override diff --git a/sql/src/main/java/io/druid/sql/avatica/DruidStatement.java b/sql/src/main/java/io/druid/sql/avatica/DruidStatement.java index cd1d0f932cd4..86048980d77d 100644 --- a/sql/src/main/java/io/druid/sql/avatica/DruidStatement.java +++ b/sql/src/main/java/io/druid/sql/avatica/DruidStatement.java @@ -22,9 +22,9 @@ import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; -import io.druid.java.util.common.concurrent.Execs; import io.druid.java.util.common.ISE; import io.druid.java.util.common.StringUtils; +import io.druid.java.util.common.concurrent.Execs; import io.druid.java.util.common.guava.Sequence; import io.druid.java.util.common.guava.Sequences; import io.druid.java.util.common.guava.Yielder; diff --git a/sql/src/main/java/io/druid/sql/calcite/planner/DruidPlanner.java b/sql/src/main/java/io/druid/sql/calcite/planner/DruidPlanner.java index cfd085b68c74..8779d793e067 100644 --- a/sql/src/main/java/io/druid/sql/calcite/planner/DruidPlanner.java +++ b/sql/src/main/java/io/druid/sql/calcite/planner/DruidPlanner.java @@ -30,9 +30,9 @@ import io.druid.server.security.Access; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthenticationResult; -import io.druid.server.security.AuthenticatorMapper; import io.druid.server.security.AuthorizationUtils; import io.druid.server.security.AuthorizerMapper; +import io.druid.server.security.Escalator; import io.druid.server.security.ForbiddenException; import io.druid.sql.calcite.rel.DruidConvention; import io.druid.sql.calcite.rel.DruidRel; @@ -71,29 +71,25 @@ public class DruidPlanner implements Closeable { private final Planner planner; private final PlannerContext plannerContext; - private final AuthConfig authConfig; private final AuthorizerMapper authorizerMapper; - private final AuthenticatorMapper authenticatorMapper; + private final Escalator escalator; public DruidPlanner( final Planner planner, final PlannerContext plannerContext, - final AuthConfig authConfig, final AuthorizerMapper authorizerMapper, - final AuthenticatorMapper authenticatorMapper + final Escalator escalator ) { this.planner = planner; this.plannerContext = plannerContext; - this.authConfig = authConfig; this.authorizerMapper = authorizerMapper; - this.authenticatorMapper = authenticatorMapper; + this.escalator = escalator; } public PlannerResult plan(final String sql) throws SqlParseException, ValidationException, RelConversionException { - AuthenticationResult authenticationResult = authenticatorMapper.getEscalatingAuthenticator() - .createEscalatedAuthenticationResult(); + AuthenticationResult authenticationResult = escalator.createEscalatedAuthenticationResult(); return plan(sql, null, authenticationResult); } diff --git a/sql/src/main/java/io/druid/sql/calcite/planner/PlannerFactory.java b/sql/src/main/java/io/druid/sql/calcite/planner/PlannerFactory.java index bfbc755a9769..843003c0b45f 100644 --- a/sql/src/main/java/io/druid/sql/calcite/planner/PlannerFactory.java +++ b/sql/src/main/java/io/druid/sql/calcite/planner/PlannerFactory.java @@ -25,8 +25,8 @@ import io.druid.math.expr.ExprMacroTable; import io.druid.server.QueryLifecycleFactory; import io.druid.server.security.AuthConfig; -import io.druid.server.security.AuthenticatorMapper; import io.druid.server.security.AuthorizerMapper; +import io.druid.server.security.Escalator; import io.druid.sql.calcite.rel.QueryMaker; import io.druid.sql.calcite.schema.DruidSchema; import org.apache.calcite.avatica.util.Casing; @@ -67,7 +67,7 @@ public class PlannerFactory private final AuthConfig authConfig; private final AuthorizerMapper authorizerMapper; - private final AuthenticatorMapper authenticatorMapper; + private final Escalator escalator; @Inject public PlannerFactory( @@ -77,8 +77,8 @@ public PlannerFactory( final ExprMacroTable macroTable, final PlannerConfig plannerConfig, final AuthConfig authConfig, - final AuthenticatorMapper authenticatorMapper, final AuthorizerMapper authorizerMapper, + final Escalator escalator, final @Json ObjectMapper jsonMapper ) { @@ -89,7 +89,7 @@ public PlannerFactory( this.plannerConfig = plannerConfig; this.authConfig = authConfig; this.authorizerMapper = authorizerMapper; - this.authenticatorMapper = authenticatorMapper; + this.escalator = escalator; this.jsonMapper = jsonMapper; } @@ -151,9 +151,8 @@ public SqlConformance conformance() return new DruidPlanner( Frameworks.getPlanner(frameworkConfig), plannerContext, - authConfig, authorizerMapper, - authenticatorMapper + escalator ); } } diff --git a/sql/src/main/java/io/druid/sql/calcite/schema/DruidSchema.java b/sql/src/main/java/io/druid/sql/calcite/schema/DruidSchema.java index 11124a9cfeba..af52973cfcfe 100644 --- a/sql/src/main/java/io/druid/sql/calcite/schema/DruidSchema.java +++ b/sql/src/main/java/io/druid/sql/calcite/schema/DruidSchema.java @@ -50,8 +50,7 @@ import io.druid.server.QueryLifecycleFactory; import io.druid.server.coordination.DruidServerMetadata; import io.druid.server.security.AuthenticationResult; -import io.druid.server.security.Authenticator; -import io.druid.server.security.AuthenticatorMapper; +import io.druid.server.security.Escalator; import io.druid.sql.calcite.planner.PlannerConfig; import io.druid.sql.calcite.table.DruidTable; import io.druid.sql.calcite.table.RowSignature; @@ -117,8 +116,8 @@ public class DruidSchema extends AbstractSchema // All segments that need to be refreshed. private final TreeSet segmentsNeedingRefresh = new TreeSet<>(SEGMENT_ORDER); - // Escalating authenticator, so we can attach an authentication result to queries we generate. - private final Authenticator escalatingAuthenticator; + // Escalator, so we can attach an authentication result to queries we generate. + private final Escalator escalator; private boolean refreshImmediately = false; private long lastRefresh = 0L; @@ -130,7 +129,7 @@ public DruidSchema( final TimelineServerView serverView, final PlannerConfig config, final ViewManager viewManager, - final AuthenticatorMapper authenticatorMapper + final Escalator escalator ) { this.queryLifecycleFactory = Preconditions.checkNotNull(queryLifecycleFactory, "queryLifecycleFactory"); @@ -139,7 +138,7 @@ public DruidSchema( this.viewManager = Preconditions.checkNotNull(viewManager, "viewManager"); this.cacheExec = ScheduledExecutors.fixed(1, "DruidSchema-Cache-%d"); this.tables = new ConcurrentHashMap<>(); - this.escalatingAuthenticator = authenticatorMapper.getEscalatingAuthenticator(); + this.escalator = escalator; serverView.registerTimelineCallback( MoreExecutors.sameThreadExecutor(), @@ -410,7 +409,7 @@ private Set refreshSegmentsForDataSource( final Sequence sequence = runSegmentMetadataQuery( queryLifecycleFactory, Iterables.limit(segments, MAX_SEGMENTS_PER_QUERY), - escalatingAuthenticator.createEscalatedAuthenticationResult() + escalator.createEscalatedAuthenticationResult() ); Yielder yielder = Yielders.each(sequence); diff --git a/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java b/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java index bc49feb80786..de3c2feee530 100644 --- a/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java +++ b/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java @@ -41,10 +41,12 @@ import io.druid.java.util.common.StringUtils; import io.druid.math.expr.ExprMacroTable; import io.druid.server.DruidNode; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.server.security.AuthenticatorMapper; import io.druid.server.security.AuthorizerMapper; +import io.druid.server.security.Escalator; import io.druid.sql.calcite.planner.Calcites; import io.druid.sql.calcite.planner.DruidOperatorTable; import io.druid.sql.calcite.planner.PlannerConfig; @@ -145,6 +147,7 @@ public void configure(Binder binder) binder.bindConstant().annotatedWith(Names.named("tlsServicePort")).to(-1); binder.bind(AuthenticatorMapper.class).toInstance(CalciteTests.TEST_AUTHENTICATOR_MAPPER); binder.bind(AuthorizerMapper.class).toInstance(CalciteTests.TEST_AUTHORIZER_MAPPER); + binder.bind(Escalator.class).toInstance(CalciteTests.TEST_AUTHENTICATOR_ESCALATOR); } } ) @@ -157,8 +160,8 @@ public void configure(Binder binder) macroTable, plannerConfig, new AuthConfig(), - CalciteTests.TEST_AUTHENTICATOR_MAPPER, CalciteTests.TEST_AUTHORIZER_MAPPER, + CalciteTests.TEST_AUTHENTICATOR_ESCALATOR, CalciteTests.getJsonMapper() ), AVATICA_CONFIG, @@ -719,8 +722,8 @@ public int getMaxRowsPerFrame() macroTable, plannerConfig, new AuthConfig(), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER, AuthTestUtils.TEST_AUTHORIZER_MAPPER, + new AllowAllEscalator(), CalciteTests.getJsonMapper() ), smallFrameConfig, diff --git a/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java b/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java index f2982102eee6..7ff4034b2b64 100644 --- a/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java +++ b/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java @@ -24,6 +24,7 @@ import io.druid.java.util.common.DateTimes; import io.druid.math.expr.ExprMacroTable; import io.druid.server.security.AllowAllAuthenticator; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.planner.Calcites; @@ -75,8 +76,8 @@ public void setUp() throws Exception macroTable, plannerConfig, new AuthConfig(), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER, AuthTestUtils.TEST_AUTHORIZER_MAPPER, + new AllowAllEscalator(), CalciteTests.getJsonMapper() ); } diff --git a/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java index 35ccbbaa9141..5fed009c6dbd 100644 --- a/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java +++ b/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java @@ -6182,8 +6182,8 @@ private List getResults( macroTable, plannerConfig, new AuthConfig(), - CalciteTests.TEST_AUTHENTICATOR_MAPPER, CalciteTests.TEST_AUTHORIZER_MAPPER, + CalciteTests.TEST_AUTHENTICATOR_ESCALATOR, CalciteTests.getJsonMapper() ); diff --git a/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java b/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java index 31db7ca651e3..853d946bf86c 100644 --- a/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java +++ b/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java @@ -30,6 +30,7 @@ import io.druid.query.QueryInterruptedException; import io.druid.query.ResourceLimitExceededException; import io.druid.server.security.AllowAllAuthenticator; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.planner.Calcites; @@ -108,8 +109,8 @@ public void setUp() throws Exception macroTable, plannerConfig, new AuthConfig(), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER, AuthTestUtils.TEST_AUTHORIZER_MAPPER, + new AllowAllEscalator(), CalciteTests.getJsonMapper() ) ); diff --git a/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java b/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java index 695646b1e3a3..65452d5f712a 100644 --- a/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java +++ b/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java @@ -32,7 +32,7 @@ import io.druid.segment.QueryableIndex; import io.druid.segment.TestHelper; import io.druid.segment.incremental.IncrementalIndexSchema; -import io.druid.server.security.AuthTestUtils; +import io.druid.server.security.AllowAllEscalator; import io.druid.sql.calcite.planner.Calcites; import io.druid.sql.calcite.planner.PlannerConfig; import io.druid.sql.calcite.table.DruidTable; @@ -146,7 +146,7 @@ public void setUp() throws Exception new TestServerInventoryView(walker.getSegments()), PLANNER_CONFIG_DEFAULT, new NoopViewManager(), - AuthTestUtils.TEST_AUTHENTICATOR_MAPPER + new AllowAllEscalator() ); schema.start(); diff --git a/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java b/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java index 6ae798e32463..a66bf2d1c67c 100644 --- a/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java +++ b/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java @@ -58,8 +58,8 @@ import io.druid.query.aggregation.DoubleSumAggregatorFactory; import io.druid.query.aggregation.FloatSumAggregatorFactory; import io.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import io.druid.query.expression.LookupExprMacro; import io.druid.query.expression.LookupEnabledTestExprMacroTable; +import io.druid.query.expression.LookupExprMacro; import io.druid.query.groupby.GroupByQuery; import io.druid.query.groupby.GroupByQueryConfig; import io.druid.query.groupby.GroupByQueryRunnerTest; @@ -97,12 +97,14 @@ import io.druid.server.security.Access; import io.druid.server.security.Action; import io.druid.server.security.AllowAllAuthenticator; +import io.druid.server.security.AllowAllEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthenticationResult; import io.druid.server.security.Authenticator; import io.druid.server.security.AuthenticatorMapper; import io.druid.server.security.Authorizer; import io.druid.server.security.AuthorizerMapper; +import io.druid.server.security.Escalator; import io.druid.server.security.Resource; import io.druid.server.security.ResourceType; import io.druid.sql.calcite.expression.SqlOperatorConversion; @@ -170,15 +172,20 @@ public AuthenticationResult authenticateJDBCContext(Map context) { return new AuthenticationResult((String) context.get("user"), "allowAll", null); } - - @Override - public AuthenticationResult createEscalatedAuthenticationResult() - { - return new AuthenticationResult(TEST_SUPERUSER_NAME, "allowAll", null); - } } ); - TEST_AUTHENTICATOR_MAPPER = new AuthenticatorMapper(defaultMap, "allowAll"); + TEST_AUTHENTICATOR_MAPPER = new AuthenticatorMapper(defaultMap); + } + public static final Escalator TEST_AUTHENTICATOR_ESCALATOR; + static { + TEST_AUTHENTICATOR_ESCALATOR = new AllowAllEscalator() { + + @Override + public AuthenticationResult createEscalatedAuthenticationResult() + { + return SUPER_USER_AUTH_RESULT; + } + }; } public static final AuthenticationResult REGULAR_USER_AUTH_RESULT = new AuthenticationResult( @@ -504,7 +511,7 @@ public static DruidSchema createMockSchema( new TestServerInventoryView(walker.getSegments()), plannerConfig, viewManager, - TEST_AUTHENTICATOR_MAPPER + TEST_AUTHENTICATOR_ESCALATOR ); schema.start(); From 9de94c209495e10b1327dc70e0b00040e7d905d7 Mon Sep 17 00:00:00 2001 From: jon-wei Date: Mon, 13 Nov 2017 16:42:48 -0800 Subject: [PATCH 2/2] PR comments --- .../druid/benchmark/query/SqlBenchmark.java | 4 +-- docs/content/configuration/auth.md | 8 +++--- .../sql/QuantileSqlAggregatorTest.java | 4 +-- .../guice/security/AuthenticatorModule.java | 7 ++++-- .../guice/security/AuthorizerModule.java | 5 ++-- .../AuthenticatorMapperModule.java | 25 +++---------------- .../AuthorizerMapperModule.java | 4 +-- .../security/AllowAllAuthenticator.java | 6 ++++- .../io/druid/server/security/AuthConfig.java | 21 +++------------- .../druid/server/security/AuthTestUtils.java | 2 +- .../druid/server/security/Authenticator.java | 2 +- .../io/druid/server/security/Authorizer.java | 2 +- .../io/druid/server/security/Escalator.java | 4 +-- ...owAllEscalator.java => NoopEscalator.java} | 2 +- .../AsyncQueryForwardingServletTest.java | 4 +-- .../io/druid/server/QueryResourceTest.java | 12 ++++----- .../server/http/DatasourcesResourceTest.java | 2 +- .../security/ResourceFilterTestHelper.java | 2 +- .../sql/avatica/DruidAvaticaHandlerTest.java | 4 +-- .../druid/sql/avatica/DruidStatementTest.java | 4 +-- .../sql/calcite/http/SqlResourceTest.java | 4 +-- .../sql/calcite/schema/DruidSchemaTest.java | 4 +-- .../druid/sql/calcite/util/CalciteTests.java | 14 +++++------ 23 files changed, 61 insertions(+), 85 deletions(-) rename server/src/main/java/io/druid/server/security/{AllowAllEscalator.java => NoopEscalator.java} (96%) diff --git a/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java b/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java index ab88b08947d3..132dd772d885 100644 --- a/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java +++ b/benchmarks/src/main/java/io/druid/benchmark/query/SqlBenchmark.java @@ -39,7 +39,7 @@ import io.druid.query.dimension.DimensionSpec; import io.druid.query.groupby.GroupByQuery; import io.druid.segment.QueryableIndex; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.planner.DruidPlanner; @@ -122,7 +122,7 @@ public void setup() throws Exception plannerConfig, new AuthConfig(), AuthTestUtils.TEST_AUTHORIZER_MAPPER, - new AllowAllEscalator(), + new NoopEscalator(), CalciteTests.getJsonMapper() ); groupByQuery = GroupByQuery diff --git a/docs/content/configuration/auth.md b/docs/content/configuration/auth.md index 8f1fe18de6eb..8beb355939c9 100644 --- a/docs/content/configuration/auth.md +++ b/docs/content/configuration/auth.md @@ -7,7 +7,7 @@ layout: doc_page |Property|Type|Description|Default|Required| |--------|-----------|--------|--------|--------| |`druid.auth.authenticationChain`|JSON List of Strings|List of Authenticator type names|["allowAll"]|no| -|`druid.escalator.type`|String|Type of the Escalator that should be used for internal Druid communications. This Escalator must have the same type as an Authenticator in `druid.auth.authenticationChain`.|"allowAll"|no| +|`druid.escalator.type`|String|Type of the Escalator that should be used for internal Druid communications. This Escalator must have the same type as an Authenticator in `druid.auth.authenticationChain`.|"noop"|no| |`druid.auth.authorizers`|JSON List of Strings|List of Authorizer type names |["allowAll"]|no| ## Enabling Authentication/Authorization @@ -36,9 +36,9 @@ This built-in Authenticator authenticates all requests, and always directs them ## Escalator The `druid.escalator.type` property determines what authentication scheme should be used for internal Druid cluster communications (such as when a broker node communicates with historical nodes for query processing). -The Escalator chosen for this property must have the same type as an Authenticator in `druid.auth.authenticationChain. Authenticator extension implementors must also provide a corresponding Escalator implementation with the same type name if they intend to use a particular authentication scheme for internal Druid communications. +The Escalator chosen for this property must use an authentication scheme that is supported by an Authenticator in `druid.auth.authenticationChain. Authenticator extension implementors must also provide a corresponding Escalator implementation if they intend to use a particular authentication scheme for internal Druid communications. -### AllowAll Escalator +### Noop Escalator This built-in default Escalator is intended for use only with the default AllowAll Authenticator and Authorizer. @@ -67,7 +67,7 @@ When `druid.auth.authenticationChain` is left empty or unspecified, Druid will c When `druid.auth.authorizers` is left empty or unspecified, Druid will create a single AllowAll Authorizer named "allowAll". -The default value of `druid.escalator.type` is "allowAll" to match the default unsecured Authenticator/Authorizer configurations. +The default value of `druid.escalator.type` is "noop" to match the default unsecured Authenticator/Authorizer configurations. ## Authenticator to Authorizer Routing diff --git a/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java b/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java index f0b7794427a6..f74ab9541369 100644 --- a/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java +++ b/extensions-core/histogram/src/test/java/io/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java @@ -43,7 +43,7 @@ import io.druid.segment.column.ValueType; import io.druid.segment.incremental.IncrementalIndexSchema; import io.druid.segment.virtual.ExpressionVirtualColumn; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.filtration.Filtration; @@ -138,7 +138,7 @@ public void setUp() throws Exception plannerConfig, new AuthConfig(), AuthTestUtils.TEST_AUTHORIZER_MAPPER, - new AllowAllEscalator(), + new NoopEscalator(), CalciteTests.getJsonMapper() ); } diff --git a/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java b/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java index 5ae6015c8b07..117758f07f7c 100644 --- a/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java +++ b/server/src/main/java/io/druid/guice/security/AuthenticatorModule.java @@ -28,6 +28,7 @@ import io.druid.guice.LazySingleton; import io.druid.guice.PolyBind; import io.druid.server.security.AllowAllAuthenticator; +import io.druid.server.security.AuthConfig; import io.druid.server.security.Authenticator; public class AuthenticatorModule implements Module @@ -39,11 +40,13 @@ public void configure(Binder binder) binder, Key.get(Authenticator.class) ); - authenticatorMapBinder.addBinding("allowAll").to(AllowAllAuthenticator.class).in(LazySingleton.class); + authenticatorMapBinder.addBinding(AuthConfig.ALLOW_ALL_NAME) + .to(AllowAllAuthenticator.class) + .in(LazySingleton.class); } @Provides - @Named("allowAll") + @Named(AuthConfig.ALLOW_ALL_NAME) public Authenticator getAuthenticator() { return new AllowAllAuthenticator(); diff --git a/server/src/main/java/io/druid/guice/security/AuthorizerModule.java b/server/src/main/java/io/druid/guice/security/AuthorizerModule.java index a27286a9a0e2..4deef3b65b28 100644 --- a/server/src/main/java/io/druid/guice/security/AuthorizerModule.java +++ b/server/src/main/java/io/druid/guice/security/AuthorizerModule.java @@ -28,6 +28,7 @@ import io.druid.guice.LazySingleton; import io.druid.guice.PolyBind; import io.druid.server.security.AllowAllAuthorizer; +import io.druid.server.security.AuthConfig; import io.druid.server.security.Authorizer; public class AuthorizerModule implements Module @@ -39,11 +40,11 @@ public void configure(Binder binder) binder, Key.get(Authorizer.class) ); - authorizerMapBinder.addBinding("allowAll").to(AllowAllAuthorizer.class).in(LazySingleton.class); + authorizerMapBinder.addBinding(AuthConfig.ALLOW_ALL_NAME).to(AllowAllAuthorizer.class).in(LazySingleton.class); } @Provides - @Named("allowAll") + @Named(AuthConfig.ALLOW_ALL_NAME) public Authorizer getAuthorizer() { return new AllowAllAuthorizer(); diff --git a/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java b/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java index a8bb321a189f..d7085721ceb9 100644 --- a/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java +++ b/server/src/main/java/io/druid/server/initialization/AuthenticatorMapperModule.java @@ -93,11 +93,11 @@ public AuthenticatorMapper get() List authenticators = authConfig.getAuthenticatorChain(); - validateProperties(props, authenticators); + validateAuthenticators(authenticators); // Default configuration is to allow all requests. if (authenticators == null) { - authenticatorMap.put("allowAll", new AllowAllAuthenticator()); + authenticatorMap.put(AuthConfig.ALLOW_ALL_NAME, new AllowAllAuthenticator()); return new AuthenticatorMapper(authenticatorMap); } @@ -129,19 +129,10 @@ public AuthenticatorMapper get() } } - private static void validateProperties(Properties properties, List authenticators) + private static void validateAuthenticators(List authenticators) { - String escalatorType = properties.getProperty("druid.escalator.type"); - if (escalatorType == null) { - escalatorType = "allowAll"; - } - if (authenticators == null) { - if (escalatorType.equals("allowAll")) { - return; - } else { - throw new ISE("Using default unsecured configuration with invalid druid.escalator.type [%s]", escalatorType); - } + return; } if (authenticators.isEmpty()) { @@ -155,13 +146,5 @@ private static void validateProperties(Properties properties, List authe } authenticatorSet.add(authenticator); } - - for (String authenticator : authenticators) { - String typeProperty = StringUtils.format("druid.auth.authenticator.%s.type", authenticator); - if (escalatorType.equals(properties.getProperty(typeProperty))) { - return; - } - } - throw new ISE("druid.escalator.type [%s] does not match any configured authenticator's type!", escalatorType); } } diff --git a/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java b/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java index 427a461aa1d4..4ba019550833 100644 --- a/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java +++ b/server/src/main/java/io/druid/server/initialization/AuthorizerMapperModule.java @@ -91,7 +91,7 @@ public AuthorizerMapper get() Map authorizerMap = Maps.newHashMap(); List authorizers = authConfig.getAuthorizers(); - validateProperties(authorizers); + validateAuthorizers(authorizers); // Default is allow all if (authorizers == null) { @@ -133,7 +133,7 @@ public Authorizer getAuthorizer(String name) } } - private static void validateProperties(List authorizers) + private static void validateAuthorizers(List authorizers) { if (authorizers == null) { return; diff --git a/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java b/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java index e525f28045ef..c87d67546ae2 100644 --- a/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java +++ b/server/src/main/java/io/druid/server/security/AllowAllAuthenticator.java @@ -35,7 +35,11 @@ */ public class AllowAllAuthenticator implements Authenticator { - public static final AuthenticationResult ALLOW_ALL_RESULT = new AuthenticationResult("allowAll", "allowAll", null); + public static final AuthenticationResult ALLOW_ALL_RESULT = new AuthenticationResult( + AuthConfig.ALLOW_ALL_NAME, + AuthConfig.ALLOW_ALL_NAME, + null + ); @Override public Class getFilterClass() diff --git a/server/src/main/java/io/druid/server/security/AuthConfig.java b/server/src/main/java/io/druid/server/security/AuthConfig.java index e93d84939706..af4768a4d5e0 100644 --- a/server/src/main/java/io/druid/server/security/AuthConfig.java +++ b/server/src/main/java/io/druid/server/security/AuthConfig.java @@ -36,29 +36,26 @@ public class AuthConfig */ public static final String DRUID_AUTHORIZATION_CHECKED = "Druid-Authorization-Checked"; + public static final String ALLOW_ALL_NAME = "allowAll"; + public AuthConfig() { - this(null, null, null); + this(null, null); } @JsonCreator public AuthConfig( @JsonProperty("authenticatorChain") List authenticationChain, - @JsonProperty("escalatedAuthenticator") String escalatedAuthenticator, @JsonProperty("authorizers") List authorizers ) { this.authenticatorChain = authenticationChain; - this.escalatedAuthenticator = escalatedAuthenticator == null ? "allowAll" : escalatedAuthenticator; this.authorizers = authorizers; } @JsonProperty private final List authenticatorChain; - @JsonProperty - private final String escalatedAuthenticator; - @JsonProperty private List authorizers; @@ -67,11 +64,6 @@ public List getAuthenticatorChain() return authenticatorChain; } - public String getEscalatedAuthenticator() - { - return escalatedAuthenticator; - } - public List getAuthorizers() { return authorizers; @@ -82,7 +74,6 @@ public String toString() { return "AuthConfig{" + "authenticatorChain='" + authenticatorChain + '\'' + - ", escalatedAuthenticator='" + escalatedAuthenticator + '\'' + ", authorizers='" + authorizers + '\'' + '}'; } @@ -104,11 +95,6 @@ public boolean equals(Object o) : that.getAuthenticatorChain() != null) { return false; } - if (getEscalatedAuthenticator() != null - ? !getEscalatedAuthenticator().equals(that.getEscalatedAuthenticator()) - : that.getEscalatedAuthenticator() != null) { - return false; - } return getAuthorizers() != null ? getAuthorizers().equals(that.getAuthorizers()) : that.getAuthorizers() == null; } @@ -117,7 +103,6 @@ public boolean equals(Object o) public int hashCode() { int result = getAuthenticatorChain() != null ? getAuthenticatorChain().hashCode() : 0; - result = 31 * result + (getEscalatedAuthenticator() != null ? getEscalatedAuthenticator().hashCode() : 0); result = 31 * result + (getAuthorizers() != null ? getAuthorizers().hashCode() : 0); return result; } diff --git a/server/src/main/java/io/druid/server/security/AuthTestUtils.java b/server/src/main/java/io/druid/server/security/AuthTestUtils.java index e07c1b6924f4..71fac1e5aeed 100644 --- a/server/src/main/java/io/druid/server/security/AuthTestUtils.java +++ b/server/src/main/java/io/druid/server/security/AuthTestUtils.java @@ -30,7 +30,7 @@ public class AuthTestUtils static { final Map defaultMap = Maps.newHashMap(); - defaultMap.put("allowAll", new AllowAllAuthenticator()); + defaultMap.put(AuthConfig.ALLOW_ALL_NAME, new AllowAllAuthenticator()); TEST_AUTHENTICATOR_MAPPER = new AuthenticatorMapper(defaultMap); TEST_AUTHORIZER_MAPPER = new AuthorizerMapper(null) { diff --git a/server/src/main/java/io/druid/server/security/Authenticator.java b/server/src/main/java/io/druid/server/security/Authenticator.java index 6525c1b7c15f..969b4497f2a5 100644 --- a/server/src/main/java/io/druid/server/security/Authenticator.java +++ b/server/src/main/java/io/druid/server/security/Authenticator.java @@ -29,7 +29,7 @@ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes(value = { - @JsonSubTypes.Type(name = "allowAll", value = AllowAllAuthenticator.class), + @JsonSubTypes.Type(name = AuthConfig.ALLOW_ALL_NAME, value = AllowAllAuthenticator.class), }) /** * This interface is essentially a ServletFilterHolder with additional requirements on the getFilter() method contract, plus: diff --git a/server/src/main/java/io/druid/server/security/Authorizer.java b/server/src/main/java/io/druid/server/security/Authorizer.java index 9cd586c9f9dc..cade33eee406 100644 --- a/server/src/main/java/io/druid/server/security/Authorizer.java +++ b/server/src/main/java/io/druid/server/security/Authorizer.java @@ -24,7 +24,7 @@ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes(value = { - @JsonSubTypes.Type(name = "allowAll", value = AllowAllAuthorizer.class) + @JsonSubTypes.Type(name = AuthConfig.ALLOW_ALL_NAME, value = AllowAllAuthorizer.class) }) /** * An Authorizer is responsible for performing authorization checks for resource accesses. diff --git a/server/src/main/java/io/druid/server/security/Escalator.java b/server/src/main/java/io/druid/server/security/Escalator.java index c8fb3279dd52..021572ed3f0a 100644 --- a/server/src/main/java/io/druid/server/security/Escalator.java +++ b/server/src/main/java/io/druid/server/security/Escalator.java @@ -23,9 +23,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.metamx.http.client.HttpClient; -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = AllowAllEscalator.class) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = NoopEscalator.class) @JsonSubTypes(value = { - @JsonSubTypes.Type(name = "allowAll", value = AllowAllEscalator.class), + @JsonSubTypes.Type(name = "noop", value = NoopEscalator.class), }) /** * This interface provides methods needed for escalating internal system requests with priveleged authentication diff --git a/server/src/main/java/io/druid/server/security/AllowAllEscalator.java b/server/src/main/java/io/druid/server/security/NoopEscalator.java similarity index 96% rename from server/src/main/java/io/druid/server/security/AllowAllEscalator.java rename to server/src/main/java/io/druid/server/security/NoopEscalator.java index 737690454550..583d12dc249a 100644 --- a/server/src/main/java/io/druid/server/security/AllowAllEscalator.java +++ b/server/src/main/java/io/druid/server/security/NoopEscalator.java @@ -21,7 +21,7 @@ import com.metamx.http.client.HttpClient; -public class AllowAllEscalator implements Escalator +public class NoopEscalator implements Escalator { @Override public HttpClient createEscalatedClient(HttpClient baseClient) diff --git a/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java b/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java index 23afdc97154f..c1c0d3b2a4ed 100644 --- a/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java +++ b/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java @@ -52,7 +52,7 @@ import io.druid.server.router.QueryHostFinder; import io.druid.server.router.RendezvousHashAvaticaConnectionBalancer; import io.druid.server.security.AllowAllAuthorizer; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.Authorizer; import io.druid.server.security.AuthorizerMapper; import org.eclipse.jetty.client.HttpClient; @@ -253,7 +253,7 @@ public void log(RequestLogLine requestLogLine) throws IOException } }, new DefaultGenericQueryMetricsFactory(jsonMapper), - new AllowAllEscalator() + new NoopEscalator() ) { @Override diff --git a/server/src/test/java/io/druid/server/QueryResourceTest.java b/server/src/test/java/io/druid/server/QueryResourceTest.java index 8a3c6147e2da..cc848181fe1d 100644 --- a/server/src/test/java/io/druid/server/QueryResourceTest.java +++ b/server/src/test/java/io/druid/server/QueryResourceTest.java @@ -266,13 +266,13 @@ public Access authorize(AuthenticationResult authenticationResult, Resource reso new NoopServiceEmitter(), testRequestLogger, serverConfig, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper ), jsonMapper, jsonMapper, queryManager, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper, new DefaultGenericQueryMetricsFactory(jsonMapper) ); @@ -374,13 +374,13 @@ public Access authorize(AuthenticationResult authenticationResult, Resource reso new NoopServiceEmitter(), testRequestLogger, serverConfig, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper ), jsonMapper, jsonMapper, queryManager, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper, new DefaultGenericQueryMetricsFactory(jsonMapper) ); @@ -496,13 +496,13 @@ public Access authorize(AuthenticationResult authenticationResult, Resource reso new NoopServiceEmitter(), testRequestLogger, serverConfig, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper ), jsonMapper, jsonMapper, queryManager, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper, new DefaultGenericQueryMetricsFactory(jsonMapper) ); diff --git a/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java b/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java index 315bfb0b4876..96e0b583f2e0 100644 --- a/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java +++ b/server/src/test/java/io/druid/server/http/DatasourcesResourceTest.java @@ -236,7 +236,7 @@ public Access authorize(AuthenticationResult authenticationResult1, Resource res inventoryView, null, null, - new AuthConfig(null, null, null), + new AuthConfig(null, null), authMapper ); Response response = datasourcesResource.getQueryableDataSources("full", null, request); diff --git a/server/src/test/java/io/druid/server/http/security/ResourceFilterTestHelper.java b/server/src/test/java/io/druid/server/http/security/ResourceFilterTestHelper.java index 2ca7b311ee59..ed39de6452ef 100644 --- a/server/src/test/java/io/druid/server/http/security/ResourceFilterTestHelper.java +++ b/server/src/test/java/io/druid/server/http/security/ResourceFilterTestHelper.java @@ -182,7 +182,7 @@ public void configure(Binder binder) for (Key key : mockableKeys) { binder.bind((Key) key).toInstance(EasyMock.createNiceMock(key.getTypeLiteral().getRawType())); } - binder.bind(AuthConfig.class).toInstance(new AuthConfig(null, null, null)); + binder.bind(AuthConfig.class).toInstance(new AuthConfig(null, null)); } } ); diff --git a/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java b/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java index de3c2feee530..bce883d1c534 100644 --- a/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java +++ b/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java @@ -41,7 +41,7 @@ import io.druid.java.util.common.StringUtils; import io.druid.math.expr.ExprMacroTable; import io.druid.server.DruidNode; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.server.security.AuthenticatorMapper; @@ -723,7 +723,7 @@ public int getMaxRowsPerFrame() plannerConfig, new AuthConfig(), AuthTestUtils.TEST_AUTHORIZER_MAPPER, - new AllowAllEscalator(), + new NoopEscalator(), CalciteTests.getJsonMapper() ), smallFrameConfig, diff --git a/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java b/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java index 7ff4034b2b64..d229549d366e 100644 --- a/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java +++ b/sql/src/test/java/io/druid/sql/avatica/DruidStatementTest.java @@ -24,7 +24,7 @@ import io.druid.java.util.common.DateTimes; import io.druid.math.expr.ExprMacroTable; import io.druid.server.security.AllowAllAuthenticator; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.planner.Calcites; @@ -77,7 +77,7 @@ public void setUp() throws Exception plannerConfig, new AuthConfig(), AuthTestUtils.TEST_AUTHORIZER_MAPPER, - new AllowAllEscalator(), + new NoopEscalator(), CalciteTests.getJsonMapper() ); } diff --git a/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java b/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java index 853d946bf86c..68d44524ae9d 100644 --- a/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java +++ b/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java @@ -30,7 +30,7 @@ import io.druid.query.QueryInterruptedException; import io.druid.query.ResourceLimitExceededException; import io.druid.server.security.AllowAllAuthenticator; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthTestUtils; import io.druid.sql.calcite.planner.Calcites; @@ -110,7 +110,7 @@ public void setUp() throws Exception plannerConfig, new AuthConfig(), AuthTestUtils.TEST_AUTHORIZER_MAPPER, - new AllowAllEscalator(), + new NoopEscalator(), CalciteTests.getJsonMapper() ) ); diff --git a/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java b/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java index 65452d5f712a..dfdef39e8362 100644 --- a/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java +++ b/sql/src/test/java/io/druid/sql/calcite/schema/DruidSchemaTest.java @@ -32,7 +32,7 @@ import io.druid.segment.QueryableIndex; import io.druid.segment.TestHelper; import io.druid.segment.incremental.IncrementalIndexSchema; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.sql.calcite.planner.Calcites; import io.druid.sql.calcite.planner.PlannerConfig; import io.druid.sql.calcite.table.DruidTable; @@ -146,7 +146,7 @@ public void setUp() throws Exception new TestServerInventoryView(walker.getSegments()), PLANNER_CONFIG_DEFAULT, new NoopViewManager(), - new AllowAllEscalator() + new NoopEscalator() ); schema.start(); diff --git a/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java b/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java index a66bf2d1c67c..476be141b805 100644 --- a/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java +++ b/sql/src/test/java/io/druid/sql/calcite/util/CalciteTests.java @@ -97,7 +97,7 @@ import io.druid.server.security.Access; import io.druid.server.security.Action; import io.druid.server.security.AllowAllAuthenticator; -import io.druid.server.security.AllowAllEscalator; +import io.druid.server.security.NoopEscalator; import io.druid.server.security.AuthConfig; import io.druid.server.security.AuthenticationResult; import io.druid.server.security.Authenticator; @@ -165,12 +165,12 @@ public Access authorize( static { final Map defaultMap = Maps.newHashMap(); defaultMap.put( - "allowAll", + AuthConfig.ALLOW_ALL_NAME, new AllowAllAuthenticator() { @Override public AuthenticationResult authenticateJDBCContext(Map context) { - return new AuthenticationResult((String) context.get("user"), "allowAll", null); + return new AuthenticationResult((String) context.get("user"), AuthConfig.ALLOW_ALL_NAME, null); } } ); @@ -178,7 +178,7 @@ public AuthenticationResult authenticateJDBCContext(Map context) } public static final Escalator TEST_AUTHENTICATOR_ESCALATOR; static { - TEST_AUTHENTICATOR_ESCALATOR = new AllowAllEscalator() { + TEST_AUTHENTICATOR_ESCALATOR = new NoopEscalator() { @Override public AuthenticationResult createEscalatedAuthenticationResult() @@ -189,14 +189,14 @@ public AuthenticationResult createEscalatedAuthenticationResult() } public static final AuthenticationResult REGULAR_USER_AUTH_RESULT = new AuthenticationResult( - "allowAll", - "allowAll", + AuthConfig.ALLOW_ALL_NAME, + AuthConfig.ALLOW_ALL_NAME, null ); public static final AuthenticationResult SUPER_USER_AUTH_RESULT = new AuthenticationResult( TEST_SUPERUSER_NAME, - "allowAll", + AuthConfig.ALLOW_ALL_NAME, null );