From 98544cc975fd7007ebf68dc24f7853e8287d893d Mon Sep 17 00:00:00 2001 From: Abraham Elmahrek Date: Thu, 5 Feb 2015 17:38:59 -0800 Subject: [PATCH] SQOOP-1982: Sqoop2: Provide username globally via AuthenticationProvider (Richard Zhou via Abraham Elmahrek) --- .../sqoop/security/AuthenticationHandler.java | 9 ++++ .../security/AuthenticationProvider.java | 30 +++++++++++ .../sqoop/security/AuthorizationHandler.java | 2 +- .../sqoop/security/AuthorizationManager.java | 14 ++++- .../sqoop/security/SecurityConstants.java | 8 +++ .../apache/sqoop/security/SecurityError.java | 8 ++- .../sqoop/security/SecurityFactory.java | 19 +++++++ dist/src/main/server/conf/sqoop.properties | 2 +- .../DefaultAuthenticationProvider.java | 54 +++++++++++++++++++ .../DefaultAuthorizationHandler.java | 14 ++++- 10 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 core/src/main/java/org/apache/sqoop/security/AuthenticationProvider.java create mode 100644 security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthenticationProvider.java diff --git a/core/src/main/java/org/apache/sqoop/security/AuthenticationHandler.java b/core/src/main/java/org/apache/sqoop/security/AuthenticationHandler.java index 6fb6d1da..6ac81927 100644 --- a/core/src/main/java/org/apache/sqoop/security/AuthenticationHandler.java +++ b/core/src/main/java/org/apache/sqoop/security/AuthenticationHandler.java @@ -33,10 +33,19 @@ public abstract class AuthenticationHandler { */ protected boolean securityEnabled = false; + /** + * AuthenticationProvider is an authentication to get userNames and groupNames. + */ + protected AuthenticationProvider authenticationProvider; + public boolean isSecurityEnabled() { return securityEnabled; } + public AuthenticationProvider getAuthenticationProvider() { + return authenticationProvider; + } + public abstract void doInitialize(); public abstract void secureLogin(); diff --git a/core/src/main/java/org/apache/sqoop/security/AuthenticationProvider.java b/core/src/main/java/org/apache/sqoop/security/AuthenticationProvider.java new file mode 100644 index 00000000..b4450fc7 --- /dev/null +++ b/core/src/main/java/org/apache/sqoop/security/AuthenticationProvider.java @@ -0,0 +1,30 @@ +/** + * 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.sqoop.security; + +/** + * AuthenticationProvider is an abstract class for authentication. The + * implementation should return userNames and groupNames. + */ +public abstract class AuthenticationProvider { + + public abstract String getUserName(); + + public abstract String[] getGroupNames(); +} diff --git a/core/src/main/java/org/apache/sqoop/security/AuthorizationHandler.java b/core/src/main/java/org/apache/sqoop/security/AuthorizationHandler.java index 51fc2dc1..5f3231be 100644 --- a/core/src/main/java/org/apache/sqoop/security/AuthorizationHandler.java +++ b/core/src/main/java/org/apache/sqoop/security/AuthorizationHandler.java @@ -31,7 +31,7 @@ */ public abstract class AuthorizationHandler { - public abstract void doInitialize() throws ClassNotFoundException, IllegalAccessException, InstantiationException; + public abstract void doInitialize(AuthenticationProvider provider) throws ClassNotFoundException, IllegalAccessException, InstantiationException; /** * Role related function diff --git a/core/src/main/java/org/apache/sqoop/security/AuthorizationManager.java b/core/src/main/java/org/apache/sqoop/security/AuthorizationManager.java index cfa7a668..7f0fe272 100644 --- a/core/src/main/java/org/apache/sqoop/security/AuthorizationManager.java +++ b/core/src/main/java/org/apache/sqoop/security/AuthorizationManager.java @@ -22,7 +22,7 @@ import org.apache.sqoop.core.Reconfigurable; import org.apache.sqoop.core.SqoopConfiguration; -/*** +/** * AuthorizationManager is responsible for managing AuthorizationHandler. */ public class AuthorizationManager implements Reconfigurable { @@ -34,6 +34,11 @@ public class AuthorizationManager implements Reconfigurable { */ public static final String DEFAULT_AUTHORIZATION_HANDLER = "org.apache.sqoop.security.Authorization.DefaultAuthorizationHandler"; + /** + * Default authentication provider + */ + public static final String DEFAULT_AUTHENTICATION_PROVIDER = "org.apache.sqoop.security.Authorization.DefaultAuthenticationProvider"; + /** * Default authorization auto upgrade option value */ @@ -93,7 +98,12 @@ public synchronized void initialize() throws ClassNotFoundException, IllegalAcce SecurityConstants.AUTHORIZATION_HANDLER, DEFAULT_AUTHORIZATION_HANDLER).trim(); authorizationHandler = SecurityFactory.getAuthorizationHandler(handler); - authorizationHandler.doInitialize(); + + String provider = SqoopConfiguration.getInstance().getContext().getString( + SecurityConstants.AUTHENTICATION_PROVIDER, + DEFAULT_AUTHENTICATION_PROVIDER).trim(); + + authorizationHandler.doInitialize(SecurityFactory.getAuthenticationProvider(provider)); LOG.info("Authorization loaded."); } diff --git a/core/src/main/java/org/apache/sqoop/security/SecurityConstants.java b/core/src/main/java/org/apache/sqoop/security/SecurityConstants.java index 3db8f43e..a9ace270 100644 --- a/core/src/main/java/org/apache/sqoop/security/SecurityConstants.java +++ b/core/src/main/java/org/apache/sqoop/security/SecurityConstants.java @@ -132,6 +132,14 @@ public final class SecurityConstants { public static final String AUTHORIZATION_VALIDATOR = PREFIX_AUTHORIZATION_CONFIG + "validator"; + /** + * The config specifies the sqoop authentication provider class. + * The default type is org.apache.sqoop.security.DefaultAuthenticationProvider + * org.apache.sqoop.security.authorization.authentication_provider. + */ + public static final String AUTHENTICATION_PROVIDER = + PREFIX_AUTHORIZATION_CONFIG + "authentication_provider"; + /** * The config specifies the token kind in delegation token. */ diff --git a/core/src/main/java/org/apache/sqoop/security/SecurityError.java b/core/src/main/java/org/apache/sqoop/security/SecurityError.java index c68b666c..322a98f1 100644 --- a/core/src/main/java/org/apache/sqoop/security/SecurityError.java +++ b/core/src/main/java/org/apache/sqoop/security/SecurityError.java @@ -49,7 +49,13 @@ public enum SecurityError implements ErrorCode { AUTH_0008("Unable to find authorization access controller"), /** The system was not able to find authorization validator. */ - AUTH_0009("Unable to find authorization validator"); + AUTH_0009("Unable to find authorization validator"), + + /** The system was not able to find authentication provider. */ + AUTH_0010("Unable to find authentication provider"), + + /** The system was not able to get authentication from http request. */ + AUTH_0011("Unable to get remote authentication from http request"); private final String message; diff --git a/core/src/main/java/org/apache/sqoop/security/SecurityFactory.java b/core/src/main/java/org/apache/sqoop/security/SecurityFactory.java index b4274108..727d3be2 100644 --- a/core/src/main/java/org/apache/sqoop/security/SecurityFactory.java +++ b/core/src/main/java/org/apache/sqoop/security/SecurityFactory.java @@ -100,4 +100,23 @@ public static AuthorizationValidator getAuthorizationValidator(String validator) } return newValidator; } + + public static AuthenticationProvider getAuthenticationProvider(String provider) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + + Class providerClass = ClassUtils.loadClass(provider); + + if (providerClass == null) { + throw new SqoopException(SecurityError.AUTH_0010, + "Authentication Provider Class is null: " + provider); + } + + AuthenticationProvider newProvider; + try { + newProvider = (AuthenticationProvider) providerClass.newInstance(); + } catch (Exception ex) { + throw new SqoopException(SecurityError.AUTH_0010, + "Authentication Provider Class is null: " + provider, ex); + } + return newProvider; + } } \ No newline at end of file diff --git a/dist/src/main/server/conf/sqoop.properties b/dist/src/main/server/conf/sqoop.properties index fbcb1fa6..f116e17d 100755 --- a/dist/src/main/server/conf/sqoop.properties +++ b/dist/src/main/server/conf/sqoop.properties @@ -164,7 +164,7 @@ org.apache.sqoop.execution.engine=org.apache.sqoop.execution.mapreduce.Mapreduce #org.apache.sqoop.security.authorization.handler=org.apache.sqoop.security.Authorization.DefaultAuthorizationHandler #org.apache.sqoop.security.authorization.access_controller=org.apache.sqoop.security.Authorization.DefaultAuthorizationAccessController #org.apache.sqoop.security.authorization.validator=org.apache.sqoop.security.Authorization.DefaultAuthorizationValidator - +#org.apache.sqoop.security.authorization.authentication_provider=org.apache.sqoop.security.Authorization.DefaultAuthenticationProvider # External connectors load path # "/path/to/external/connectors/": Add all the connector JARs in the specified folder diff --git a/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthenticationProvider.java b/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthenticationProvider.java new file mode 100644 index 00000000..547040b3 --- /dev/null +++ b/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthenticationProvider.java @@ -0,0 +1,54 @@ +/** + * 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.sqoop.security.Authorization; + +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation; +import org.apache.sqoop.common.SqoopException; +import org.apache.sqoop.security.AuthenticationProvider; +import org.apache.sqoop.security.SecurityError; + +public class DefaultAuthenticationProvider extends AuthenticationProvider { + + @Override + public String[] getGroupNames() { + return getRemoteUGI().getGroupNames(); + } + + @Override + public String getUserName() { + return getRemoteUGI().getShortUserName(); + } + + private UserGroupInformation getRemoteUGI() { + UserGroupInformation ugi = null; + try { + ugi = HttpUserGroupInformation.get(); + } catch (Exception e) { + throw new SqoopException(SecurityError.AUTH_0011, + "Unable to get remote authentication from http request", e); + } + + if (ugi == null) { + throw new SqoopException(SecurityError.AUTH_0011, + "Unable to get remote authentication from http request"); + } + return ugi; + } +} \ No newline at end of file diff --git a/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthorizationHandler.java b/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthorizationHandler.java index 9cd2e338..8e63b86f 100644 --- a/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthorizationHandler.java +++ b/security/src/main/java/org/apache/sqoop/security/Authorization/DefaultAuthorizationHandler.java @@ -47,6 +47,8 @@ public class DefaultAuthorizationHandler extends AuthorizationHandler { protected AuthorizationValidator authorizationValidator; + protected AuthenticationProvider authenticationProvider; + public AuthorizationValidator getAuthorizationValidator() { return authorizationValidator; } @@ -63,7 +65,15 @@ public void setAuthorizationAccessController(AuthorizationAccessController autho this.authorizationAccessController = authorizationAccessController; } - public void doInitialize() throws ClassNotFoundException, IllegalAccessException, InstantiationException { + public AuthenticationProvider getAuthenticationProvider() { + return authenticationProvider; + } + + public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) { + this.authenticationProvider = authenticationProvider; + } + + public void doInitialize(AuthenticationProvider provider) throws ClassNotFoundException, IllegalAccessException, InstantiationException { MapContext mapContext = SqoopConfiguration.getInstance().getContext(); String accessController = mapContext.getString( SecurityConstants.AUTHORIZATION_ACCESS_CONTROLLER, @@ -74,6 +84,8 @@ public void doInitialize() throws ClassNotFoundException, IllegalAccessException SecurityConstants.AUTHORIZATION_VALIDATOR, DEFAULT_AUTHORIZATION_VALIDATOR).trim(); this.authorizationValidator = SecurityFactory.getAuthorizationValidator(validator); + + this.authenticationProvider = provider; } /**