Commit 34f51a2a by Hemanth Yamijala

ATLAS-661 REST API Authentication (nixonrodrigues via yhemanth)

parent 1ddf3137
......@@ -32,6 +32,7 @@ import org.apache.atlas.typesystem.Struct;
import org.apache.atlas.typesystem.json.InstanceSerialization;
import org.apache.atlas.typesystem.json.TypesSerialization;
import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.configuration.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.api.Database;
......@@ -43,12 +44,12 @@ import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
import org.apache.hadoop.hive.ql.metadata.Hive;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.metadata.Table;
import org.apache.hadoop.security.UserGroupInformation;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
......@@ -533,9 +534,18 @@ public class HiveMetaStoreBridge {
}
public static void main(String[] argv) throws Exception {
Configuration atlasConf = ApplicationProperties.get();
String atlasEndpoint = atlasConf.getString(ATLAS_ENDPOINT, DEFAULT_DGI_URL);
AtlasClient atlasClient = new AtlasClient(atlasEndpoint);
AtlasClient atlasClient;
if (!AuthenticationUtil.isKerberosAuthicationEnabled()) {
String[] basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
atlasClient = new AtlasClient(new String[]{atlasEndpoint}, basicAuthUsernamePassword);
} else {
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
atlasClient = new AtlasClient(ugi, ugi.getShortUserName(), atlasEndpoint);
}
HiveMetaStoreBridge hiveMetaStoreBridge = new HiveMetaStoreBridge(new HiveConf(), atlasClient);
hiveMetaStoreBridge.registerHiveDataModel();
......
......@@ -18,6 +18,7 @@
package org.apache.atlas;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
......@@ -27,6 +28,7 @@ import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.configuration.Configuration;
/**
* An application that allows users to run admin commands against an Atlas server.
*
......@@ -60,7 +62,14 @@ public class AtlasAdminClient {
Configuration configuration = ApplicationProperties.get();
String atlasServerUri = configuration.getString(
AtlasConstants.ATLAS_REST_ADDRESS_KEY, AtlasConstants.DEFAULT_ATLAS_REST_ADDRESS);
AtlasClient atlasClient = new AtlasClient(atlasServerUri);
AtlasClient atlasClient = null;
if (!AuthenticationUtil.isKerberosAuthicationEnabled()) {
String[] basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
atlasClient = new AtlasClient(new String[]{atlasServerUri}, basicAuthUsernamePassword);
} else {
atlasClient = new AtlasClient(atlasServerUri, null, null);
}
return handleCommand(commandLine, atlasServerUri, atlasClient);
}
......
......@@ -36,6 +36,7 @@ import org.apache.atlas.typesystem.types.AttributeDefinition;
import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.security.UserGroupInformation;
......@@ -44,7 +45,6 @@ import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
......@@ -55,7 +55,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import static org.apache.atlas.security.SecurityProperties.TLS_ENABLED;
/**
......@@ -125,6 +125,16 @@ public class AtlasClient {
private WebResource service;
private AtlasClientContext atlasClientContext;
private Configuration configuration;
private String basicAuthUser;
private String basicAuthPassword;
// New constuctor for Basic auth
public AtlasClient(String[] baseUrl, String[] basicAuthUserNamepassword) {
this.basicAuthUser = basicAuthUserNamepassword[0];
this.basicAuthPassword = basicAuthUserNamepassword[1];
initializeState(baseUrl, null, null);
}
/**
* Create a new Atlas client.
......@@ -170,6 +180,12 @@ public class AtlasClient {
private void initializeState(String[] baseUrls, UserGroupInformation ugi, String doAsUser) {
configuration = getClientProperties();
Client client = getClient(configuration, ugi, doAsUser);
if ((!AuthenticationUtil.isKerberosAuthicationEnabled()) && basicAuthUser!=null && basicAuthPassword!=null) {
final HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter(basicAuthUser, basicAuthPassword);
client.addFilter(authFilter);
}
String activeServiceUrl = determineActiveServiceURL(baseUrls, client);
atlasClientContext = new AtlasClientContext(baseUrls, client, ugi, doAsUser);
service = client.resource(UriBuilder.fromUri(activeServiceUrl).build());
......@@ -195,9 +211,14 @@ public class AtlasClient {
LOG.info("Error processing client configuration.", e);
}
URLConnectionClientHandler handler =
SecureClientUtils.getClientConnectionHandler(config, clientConfig, doAsUser, ugi);
URLConnectionClientHandler handler = null;
if ((!AuthenticationUtil.isKerberosAuthicationEnabled()) && basicAuthUser!=null && basicAuthPassword!=null) {
handler = new URLConnectionClientHandler();
} else {
handler =
SecureClientUtils.getClientConnectionHandler(config, clientConfig, doAsUser, ugi);
}
Client client = new Client(handler, config);
client.setReadTimeout(readTimeout);
client.setConnectTimeout(connectTimeout);
......@@ -1049,6 +1070,8 @@ public class AtlasClient {
public AtlasClientContext(String[] baseUrls, Client client, UserGroupInformation ugi, String doAsUser) {
this.baseUrls = baseUrls;
this.client = client;
this.ugi = ugi;
this.doAsUser = doAsUser;
}
public Client getClient() {
......@@ -1068,4 +1091,5 @@ public class AtlasClient {
}
}
}
/**
* 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.atlas.utils;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
import org.apache.commons.configuration.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* Util class for Authentication.
*/
public final class AuthenticationUtil {
private static final Logger LOG = LoggerFactory.getLogger(AuthenticationUtil.class);
private AuthenticationUtil() {
}
public static boolean isKerberosAuthicationEnabled() {
boolean isKerberosAuthicationEnabled = false;
try {
Configuration atlasConf = ApplicationProperties.get();
if ("true".equalsIgnoreCase(atlasConf.getString("atlas.http.authentication.enabled"))
&& "kerberos".equalsIgnoreCase(atlasConf.getString("atlas.http.authentication.type"))) {
isKerberosAuthicationEnabled = true;
} else {
isKerberosAuthicationEnabled = false;
}
} catch (AtlasException e) {
LOG.error("Error while isKerberosAuthicationEnabled ", e);
}
return isKerberosAuthicationEnabled;
}
public static String[] getBasicAuthenticationInput() {
String username = null;
String password = null;
try {
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter username for atlas :-");
username = bufferRead.readLine();
System.out.println("Enter password for atlas :-");
password = bufferRead.readLine();
} catch (Exception e) {
System.out.print("Error while reading ");
System.exit(1);
}
return new String[]{username, password};
}
}
......@@ -74,31 +74,12 @@
});
};
Utils.defaultErrorHandler = function(model, error) {
/*
require(['views/common/ErrorView', 'App'], function(vError, App) {
if (error.status == 404) {
App.rContent.show(new vError({
status: error.status
}));
} else if (error.status == 401) {
App.rContent.show(new vError({
status: error.status
}));
} else if (error.status == 419) {
window.location = 'login.jsp'
} else if (error.status == "0") {
var diffTime = (new Date().getTime() - prevNetworkErrorTime);
if (diffTime > 3000) {
prevNetworkErrorTime = new Date().getTime();
Utils.notifyError({
content: "Network Connection Failure : " +
"It seems you are not connected to the internet. Please check your internet connection and try again"
})
if (error.status == 401) {
window.location = '/login.jsp'
} else if (error.status == 419) {
window.location = '/login.jsp'
}
}
}
});
*/
};
Utils.localStorage = {
......
#username=password
admin=admin
user=user123
#username=group::sha256-password
admin=ADMIN::8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
michael=DATA_SCIENTIST::95bfb24de17d285d734b9eaa9109bfe922adc85f20d2e5e66a78bddb4a4ebddb
paul=DATA_STEWARD::e7c0dcf5f8a93e93791e9bac1ae454a691c1d2a902fc4256d489e96c1b9ac68c
......@@ -3,6 +3,7 @@ Apache Atlas Release Notes
--trunk - unreleased
INCOMPATIBLE CHANGES:
ATLAS-661 REST API Authentication (nixonrodrigues via yhemanth)
ATLAS-672 UI: Make dashboard v2 the default UI implementation (bergenholtz via yhemanth)
ATLAS-532 Change Data types of all timestamps in Hive model(currently long)(sumasai via yhemanth)
ATLAS-622 Introduce soft delete (shwethags)
......
......@@ -18,6 +18,7 @@
package org.apache.atlas.examples;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
......@@ -39,9 +40,9 @@ import org.apache.atlas.typesystem.types.Multiplicity;
import org.apache.atlas.typesystem.types.StructTypeDefinition;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.commons.configuration.Configuration;
import org.codehaus.jettison.json.JSONArray;
import java.util.List;
/**
......@@ -70,8 +71,24 @@ public class QuickStart {
public static final String INPUT_TABLES_ATTRIBUTE = "inputTables";
public static void main(String[] args) throws Exception {
String[] basicAuthUsernamePassword = null;
if (!AuthenticationUtil.isKerberosAuthicationEnabled()) {
basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
}
runQuickstart(args, basicAuthUsernamePassword);
}
@VisibleForTesting
static void runQuickstart(String[] args, String[] basicAuthUsernamePassword) throws Exception {
String baseUrl = getServerUrl(args);
QuickStart quickStart = new QuickStart(baseUrl);
QuickStart quickStart;
if (!AuthenticationUtil.isKerberosAuthicationEnabled()) {
quickStart = new QuickStart(baseUrl, basicAuthUsernamePassword);
} else {
quickStart = new QuickStart(baseUrl);
}
// Shows how to create types in Atlas for your meta model
quickStart.createTypes();
......@@ -111,11 +128,17 @@ public class QuickStart {
private final AtlasClient metadataServiceClient;
QuickStart(String baseUrl,String[] basicAuthUsernamePassword) {
String[] urls = baseUrl.split(",");
metadataServiceClient = new AtlasClient(urls,basicAuthUsernamePassword);
}
QuickStart(String baseUrl) throws AtlasException {
String[] urls = baseUrl.split(",");
metadataServiceClient = new AtlasClient(urls);
}
void createTypes() throws Exception {
TypesDef typesDef = createTypeDefinitions();
......
......@@ -20,8 +20,11 @@ package org.apache.atlas.web.dao;
import com.google.common.annotations.VisibleForTesting;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.atlas.web.security.AtlasAuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
......@@ -29,7 +32,13 @@ import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
import org.apache.atlas.web.model.User;
import org.apache.commons.configuration.Configuration;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.security.MessageDigest;
import org.springframework.security.core.AuthenticationException;
import org.springframework.util.StringUtils;
@Repository
public class UserDao {
......@@ -65,21 +74,59 @@ public class UserDao {
}
public User loadUserByUsername(final String username)
throws UsernameNotFoundException {
String password = userLogins.getProperty(username);
if (password == null || password.isEmpty()) {
throws AuthenticationException {
String userdetailsStr = userLogins.getProperty(username);
if (userdetailsStr == null || userdetailsStr.isEmpty()) {
throw new UsernameNotFoundException("Username not found."
+ username);
}
User user = new User();
user.setUsername(username);
user.setPassword(password);
return user;
String password = "";
String role = "";
String dataArr[] = userdetailsStr.split("::");
if (dataArr != null && dataArr.length == 2) {
role = dataArr[0];
password = dataArr[1];
} else {
LOG.error("User role credentials is not set properly for " + username);
throw new AtlasAuthenticationException("User role credentials is not set properly for " + username );
}
List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
if (StringUtils.hasText(role)) {
grantedAuths.add(new SimpleGrantedAuthority(role));
} else {
LOG.error("User role credentials is not set properly for " + username);
throw new AtlasAuthenticationException("User role credentials is not set properly for " + username );
}
User userDetails = new User(username, password, grantedAuths);
return userDetails;
}
@VisibleForTesting
public void setUserLogins(Properties userLogins) {
this.userLogins = userLogins;
}
public static String getSha256Hash(String base) throws AtlasAuthenticationException {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(base.getBytes("UTF-8"));
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (Exception ex) {
throw new AtlasAuthenticationException("Exception while encoding password.", ex);
}
}
}
......@@ -21,8 +21,6 @@ import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.atlas.Atlas;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
......@@ -31,15 +29,23 @@ import org.springframework.security.web.authentication.LoginUrlAuthenticationEnt
@SuppressWarnings("deprecation")
class AtlasAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
private static final Logger LOG = LoggerFactory.getLogger(Atlas.class);
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthenticationEntryPoint.class);
private String loginPath = "/login.jsp";
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
LOG.debug("redirecting to login page loginPath" + loginPath);
response.sendRedirect(loginPath);
String ajaxRequestHeader = request.getHeader("X-Requested-With");
response.setHeader("X-Frame-Options", "DENY");
if ("XMLHttpRequest".equals(ajaxRequestHeader)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
LOG.debug("redirecting to login page loginPath" + loginPath);
response.sendRedirect(loginPath);
}
}
}
......@@ -25,16 +25,12 @@ import javax.annotation.PostConstruct;
import org.apache.atlas.util.PropertiesUtil;
import org.apache.atlas.web.model.User;
import org.apache.log4j.Logger;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.authentication.BindAuthenticator;
import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.stereotype.Component;
@Component
......@@ -44,6 +40,7 @@ public class AtlasADAuthenticationProvider extends
.getLogger(AtlasADAuthenticationProvider.class);
private String adURL;
private String adDomain;
private String adBindDN;
private String adBindPassword;
private String adUserSearchFilter;
......@@ -74,17 +71,10 @@ public class AtlasADAuthenticationProvider extends
if (authentication.getCredentials() != null) {
userPassword = authentication.getCredentials().toString();
}
LdapContextSource ldapContextSource = getLdapContextSource();
if (adUserSearchFilter == null
|| adUserSearchFilter.trim().isEmpty()) {
adUserSearchFilter = "(sAMAccountName={0})";
}
BindAuthenticator bindAuthenticator = getBindAuthenticator(ldapContextSource);
ActiveDirectoryLdapAuthenticationProvider adAuthenticationProvider =
new ActiveDirectoryLdapAuthenticationProvider(adDomain, adURL);
LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(
bindAuthenticator);
if (userName != null && userPassword != null
&& !userName.trim().isEmpty()
&& !userPassword.trim().isEmpty()) {
......@@ -93,9 +83,7 @@ public class AtlasADAuthenticationProvider extends
grantedAuths);
final Authentication finalAuthentication = new UsernamePasswordAuthenticationToken(
principal, userPassword, grantedAuths);
authentication = ldapAuthenticationProvider
.authenticate(finalAuthentication);
authentication = getAuthenticationWithGrantedAuthority(authentication);
authentication = adAuthenticationProvider.authenticate(finalAuthentication);
return authentication;
} else {
throw new AtlasAuthenticationException(
......@@ -109,6 +97,7 @@ public class AtlasADAuthenticationProvider extends
}
private void setADProperties() {
adDomain = PropertiesUtil.getProperty("atlas.ad.domain", adDomain);
adURL = PropertiesUtil.getProperty("atlas.ad.url", adURL);
adBindDN = PropertiesUtil.getProperty("atlas.ad.bind.dn", adBindDN);
adBindPassword = PropertiesUtil.getProperty("atlas.ad.bind.password",
......@@ -122,32 +111,4 @@ public class AtlasADAuthenticationProvider extends
adDefaultRole);
}
private LdapContextSource getLdapContextSource() throws Exception {
LdapContextSource ldapContextSource = new DefaultSpringSecurityContextSource(
adURL);
ldapContextSource.setUserDn(adBindDN);
ldapContextSource.setPassword(adBindPassword);
ldapContextSource.setReferral(adReferral);
ldapContextSource.setCacheEnvironmentProperties(true);
ldapContextSource.setAnonymousReadOnly(false);
ldapContextSource.setPooled(true);
ldapContextSource.afterPropertiesSet();
return ldapContextSource;
}
private BindAuthenticator getBindAuthenticator(
LdapContextSource ldapContextSource) throws Exception {
FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(
adBase, adUserSearchFilter, ldapContextSource);
userSearch.setSearchSubtree(true);
BindAuthenticator bindAuthenticator = new BindAuthenticator(
ldapContextSource);
bindAuthenticator.setUserSearch(userSearch);
bindAuthenticator.afterPropertiesSet();
return bindAuthenticator;
}
}
......@@ -67,7 +67,7 @@ public abstract class AtlasAbstractAuthenticationProvider implements
*/
protected List<GrantedAuthority> getAuthorities(String username) {
final List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
grantedAuths.add(new SimpleGrantedAuthority("DATA_SCIENTIST"));
return grantedAuths;
}
......
......@@ -18,6 +18,7 @@
package org.apache.atlas.web.security;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -70,12 +71,20 @@ public class AtlasAuthenticationProvider extends
.authenticate(authentication);
} else if (atlasAuthenticationMethod.equalsIgnoreCase(AUTH_METHOD.LDAP
.name())) {
authentication = ldapAuthenticationProvider
.authenticate(authentication);
try {
authentication = ldapAuthenticationProvider
.authenticate(authentication);
} catch (Exception ex) {
LOG.error("Error while LDAP authentication", ex);
}
} else if (atlasAuthenticationMethod.equalsIgnoreCase(AUTH_METHOD.AD
.name())) {
authentication = adAuthenticationProvider
.authenticate(authentication);
try {
authentication = adAuthenticationProvider
.authenticate(authentication);
} catch (Exception ex) {
LOG.error("Error while AD authentication", ex);
}
} else {
LOG.error("Invalid authentication method :"
+ atlasAuthenticationMethod);
......@@ -84,10 +93,20 @@ public class AtlasAuthenticationProvider extends
if (authentication != null && authentication.isAuthenticated()) {
return authentication;
} else {
LOG.error("Authentication failed.");
throw new AtlasAuthenticationException("Authentication failed.");
// If the LDAP/AD authentication fails try the local file login method
if (atlasAuthenticationMethod.equalsIgnoreCase(AUTH_METHOD.AD
.name()) || atlasAuthenticationMethod.equalsIgnoreCase(AUTH_METHOD.LDAP
.name())) {
authentication = fileAuthenticationProvider
.authenticate(authentication);
}
if (authentication != null && authentication.isAuthenticated()) {
return authentication;
} else {
LOG.error("Authentication failed.");
throw new AtlasAuthenticationException("Authentication failed.");
}
}
}
}
......@@ -18,6 +18,7 @@ package org.apache.atlas.web.security;
import java.util.Collection;
import org.apache.atlas.web.dao.UserDao;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
......@@ -28,6 +29,7 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
@Component
public class AtlasFileAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
......@@ -46,6 +48,7 @@ public class AtlasFileAuthenticationProvider extends AtlasAbstractAuthentication
throw new BadCredentialsException(
"Username can't be null or empty.");
}
if (password == null || password.isEmpty()) {
logger.error("Password can't be null or empty.");
throw new BadCredentialsException(
......@@ -53,16 +56,16 @@ public class AtlasFileAuthenticationProvider extends AtlasAbstractAuthentication
}
UserDetails user = userDetailsService.loadUserByUsername(username);
if (!password.equals(user.getPassword())) {
String encodedPassword = UserDao.getSha256Hash(password);
if (!encodedPassword.equals(user.getPassword())) {
logger.error("Wrong password " + username);
throw new BadCredentialsException("Wrong password");
}
Collection<? extends GrantedAuthority> authorities = getAuthorities(username);
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
authentication = new UsernamePasswordAuthenticationToken(username, password, authorities);
authentication = getAuthenticationWithGrantedAuthority(authentication);
return authentication;
}
......
......@@ -19,9 +19,7 @@
package org.apache.atlas.web.security;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.atlas.util.PropertiesUtil;
import org.apache.atlas.web.model.User;
import org.apache.log4j.Logger;
......@@ -107,9 +105,7 @@ public class AtlasLdapAuthenticationProvider extends
grantedAuths);
final Authentication finalAuthentication = new UsernamePasswordAuthenticationToken(
principal, userPassword, grantedAuths);
authentication = ldapAuthenticationProvider
.authenticate(finalAuthentication);
authentication = getAuthenticationWithGrantedAuthority(authentication);
authentication = ldapAuthenticationProvider.authenticate(finalAuthentication);
return authentication;
} else {
throw new AtlasAuthenticationException(
......@@ -168,7 +164,6 @@ public class AtlasLdapAuthenticationProvider extends
defaultLdapAuthoritiesPopulator
.setGroupSearchFilter(ldapGroupSearchFilter);
defaultLdapAuthoritiesPopulator.setIgnorePartialResultException(true);
return defaultLdapAuthoritiesPopulator;
}
......
......@@ -34,7 +34,7 @@
<property>
<name>atlas.ldap.group.searchfilter</name>
<display-name>Group Search Filter</display-name>
<value>(member=uid={0},ou=People,dc=example,dc=com)
<value>(member=uid={0},ou=Users,dc=example,dc=com)
</value>
<description></description>
</property>
......@@ -91,18 +91,22 @@
<!-- #AD info start -->
<property>
<name>atlas.ad.url</name>
<value>ldap://172.25.16.111:389</value>
<value>ldap://13.76.128.185:389</value>
<description></description>
</property>
<property>
<name>atlas.ad.domain</name>
<value>example.com</value>
<description>Ad Domain</description>
</property>
<property>
<name>atlas.ad.bind.dn</name>
<value>CN=team,CN=Users,DC=SME,DC=support,DC=com</value>
<value>CN=adadmin admin,CN=Users,DC=example,DC=com</value>
<description>AD bind dn or manager dn</description>
</property>
<property>
<name>atlas.ad.bind.password</name>
<value>Abcd1234!!</value>
<value>p@ssword</value>
<description>AD bind password</description>
</property>
<property>
......@@ -113,7 +117,7 @@
</property>
<property>
<name>atlas.ad.base.dn</name>
<value>DC=SME,DC=support,DC=com</value>
<value>dc=example,dc=com</value>
<description>AD base dn or search base</description>
</property>
<property>
......
......@@ -11,13 +11,13 @@
language governing permissions and limitations under the License. -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
......@@ -28,65 +28,62 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<security:http pattern="/login.jsp" security="none" />
<security:http pattern="/css/**" security="none" />
<security:http pattern="/lib/**" security="none" />
<security:http pattern="/login.jsp" security="none" />
<security:http pattern="/css/**" security="none" />
<security:http pattern="/lib/**" security="none" />
<security:http disable-url-rewriting="true"
use-expressions="true" create-session="always"
entry-point-ref="authenticationProcessingFilterEntryPoint">
<security:session-management
session-fixation-protection="newSession" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<security:custom-filter position="FORM_LOGIN_FILTER"
ref="atlasUsernamePasswordAuthenticationFilter" />
<security:logout delete-cookies="JSESSIONID"
logout-url="/logout.html" />
<http-basic entry-point-ref="authenticationProcessingFilterEntryPoint" />
</security:http>
<security:http disable-url-rewriting="true"
use-expressions="true" create-session="always"
entry-point-ref="entryPoint">
<security:session-management
session-fixation-protection="newSession" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<beans:bean id="atlasUsernamePasswordAuthenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager"
ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler"
ref="ajaxAuthSuccessHandler" />
<beans:property name="authenticationFailureHandler"
ref="ajaxAuthFailureHandler" />
</beans:bean>
<form-login
login-page="/login.jsp"
default-target-url="/index.html"
authentication-failure-url="/login.jsp?error=true"
username-parameter="j_username"
password-parameter="j_password" />
<beans:bean id="authenticationProcessingFilterEntryPoint"
<security:logout logout-success-url="/login.jsp" delete-cookies="JSESSIONID"
logout-url="/logout.html" />
<http-basic />
</security:http>
<beans:bean id="formAuthenticationEntryPoint"
class="org.apache.atlas.web.filters.AtlasAuthenticationEntryPoint">
<beans:property name="loginFormUrl"
value="/login.jsp" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
<beans:property name="loginFormUrl" value="/login.jsp" />
</beans:bean>
<beans:bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<beans:property name="realmName" value="atlas.com" />
</beans:bean>
<beans:bean id="ajaxAuthSuccessHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl"
value="/index.html" />
</beans:bean>
<beans:bean id="entryPoint" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<beans:constructor-arg>
<beans:map>
<beans:entry key="hasHeader('User-Agent','Mozilla')" value-ref="formAuthenticationEntryPoint" />
</beans:map>
</beans:constructor-arg>
<beans:property name="defaultEntryPoint" ref="authenticationEntryPoint"/>
</beans:bean>
<beans:bean id="ajaxAuthFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl"
value="/login.jsp?login_error=true " />
</beans:bean>
<beans:bean id="atlasAuthenticationProvider"
<beans:bean id="atlasAuthenticationProvider"
class="org.apache.atlas.web.security.AtlasAuthenticationProvider">
</beans:bean>
</beans:bean>
<security:authentication-manager
alias="authenticationManager">
<security:authentication-provider
ref="atlasAuthenticationProvider" />
</security:authentication-manager>
<security:authentication-manager
alias="authenticationManager">
<security:authentication-provider
ref="atlasAuthenticationProvider" />
</security:authentication-manager>
<security:global-method-security
pre-post-annotations="enabled" />
<security:global-method-security
pre-post-annotations="enabled" />
<context:component-scan base-package="org.apache.atlas.web" />
<context:component-scan base-package="org.apache.atlas.web" />
</beans:beans>
......@@ -38,6 +38,16 @@
-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
......@@ -63,14 +73,6 @@
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
\ No newline at end of file
......@@ -39,7 +39,8 @@ public class QuickStartIT extends BaseResourceIT {
@BeforeClass
public void runQuickStart() throws Exception {
super.setUp();
QuickStart.main(new String[]{});
QuickStart.runQuickstart(new String[]{}, new String[]{"admin", "admin"});
}
@Test
......
......@@ -49,6 +49,7 @@ import org.apache.atlas.typesystem.types.StructTypeDefinition;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.TypeUtils;
import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.atlas.utils.ParamChecker;
import org.apache.atlas.web.util.Servlets;
import org.apache.commons.configuration.Configuration;
......@@ -87,7 +88,12 @@ public abstract class BaseResourceIT {
client.resource(UriBuilder.fromUri(baseUrl).build());
service = client.resource(UriBuilder.fromUri(baseUrl).build());
serviceClient = new AtlasClient(baseUrl);
if (!AuthenticationUtil.isKerberosAuthicationEnabled()) {
serviceClient = new AtlasClient(new String[]{baseUrl}, new String[]{"admin", "admin"});
} else {
serviceClient = new AtlasClient(baseUrl);
}
}
protected void createType(TypesDef typesDef) throws Exception {
......
......@@ -19,6 +19,7 @@
package org.apache.atlas.web.security;
import java.io.File;
import java.util.Collection;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.web.TestUtils;
import org.apache.commons.configuration.PropertiesConfiguration;
......@@ -31,6 +32,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
......@@ -87,9 +89,11 @@ public class FileAuthenticationTest {
private void setupUserCredential(String tmpDir) throws Exception {
StringBuilder credentialFileStr = new StringBuilder(1024);
credentialFileStr.append("admin=admin123\n");
credentialFileStr.append("user=user123\n");
credentialFileStr.append("test=test123\n");
credentialFileStr.append("admin=ADMIN::8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918\n");
credentialFileStr.append("michael=DATA_SCIENTIST::95bfb24de17d285d734b9eaa9109bfe922adc85f20d2e5e66a78bddb4a4ebddb\n");
credentialFileStr.append("paul=DATA_STEWARD::e7c0dcf5f8a93e93791e9bac1ae454a691c1d2a902fc4256d489e96c1b9ac68c\n");
credentialFileStr.append("user= \n");
credentialFileStr.append("user12= ::bd35283fe8fcfd77d7c05a8bf2adb85c773281927e12c9829c72a9462092f7c4\n");
File credentialFile = new File(tmpDir, "users-credentials");
FileUtils.write(credentialFile, credentialFileStr.toString());
}
......@@ -98,7 +102,7 @@ public class FileAuthenticationTest {
public void testValidUserLogin() {
when(authentication.getName()).thenReturn("admin");
when(authentication.getCredentials()).thenReturn("admin123");
when(authentication.getCredentials()).thenReturn("admin");
Authentication auth = authProvider.authenticate(authentication);
LOG.debug(" " + auth);
......@@ -133,6 +137,54 @@ public class FileAuthenticationTest {
}
}
@Test
public void testLoginWhenRoleIsNotSet() {
when(authentication.getName()).thenReturn("user12"); // for this user role is not set properly
when(authentication.getCredentials()).thenReturn("user12");
try {
Authentication auth = authProvider.authenticate(authentication);
LOG.debug(" " + auth);
} catch (AtlasAuthenticationException uExp) {
Assert.assertTrue(uExp.getMessage().startsWith("User role credentials is not set properly for"));
}
}
@Test
public void testLoginWhenRolePasswordNotSet() {
when(authentication.getName()).thenReturn("user"); // for this user password details are set blank
when(authentication.getCredentials()).thenReturn("P@ssword");
try {
Authentication auth = authProvider.authenticate(authentication);
LOG.debug(" " + auth);
} catch (UsernameNotFoundException uExp) {
Assert.assertTrue(uExp.getMessage().startsWith("Username not found"));
}
}
@Test
public void testUserRoleMapping() {
when(authentication.getName()).thenReturn("admin");
when(authentication.getCredentials()).thenReturn("admin");
Authentication auth = authProvider.authenticate(authentication);
LOG.debug(" " + auth);
Assert.assertTrue(auth.isAuthenticated());
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
String role = "";
for (GrantedAuthority gauth : authorities) {
role = gauth.getAuthority();
}
Assert.assertTrue("ADMIN".equals(role));
}
@AfterClass
public void tearDown() throws Exception {
......
......@@ -60,7 +60,6 @@ public class NegativeSSLAndKerberosTest extends BaseSSLAndKerberosTest {
// client will actually only leverage subset of these properties
final PropertiesConfiguration configuration = getSSLConfiguration(providerUrl);
configuration.setProperty("atlas.http.authentication.type", "kerberos");
TestUtils.writeConfiguration(configuration, persistDir + File.separator +
ApplicationProperties.APPLICATION_PROPERTIES);
......@@ -76,6 +75,7 @@ public class NegativeSSLAndKerberosTest extends BaseSSLAndKerberosTest {
configuration.setProperty(TLS_ENABLED, true);
configuration.setProperty("atlas.http.authentication.enabled", "true");
configuration.setProperty("atlas.http.authentication.type", "kerberos");
configuration.setProperty("atlas.http.authentication.kerberos.principal", "HTTP/localhost@" + kdc.getRealm());
configuration.setProperty("atlas.http.authentication.kerberos.keytab", httpKeytabFile.getAbsolutePath());
configuration.setProperty("atlas.http.authentication.kerberos.name.rules",
......@@ -84,6 +84,10 @@ public class NegativeSSLAndKerberosTest extends BaseSSLAndKerberosTest {
TestUtils.writeConfiguration(configuration, persistDir + File.separator +
ApplicationProperties.APPLICATION_PROPERTIES);
// save original setting
originalConf = System.getProperty("atlas.conf");
System.setProperty("atlas.conf", persistDir);
dgiClient = new AtlasClient(DGI_URL) {
@Override
protected PropertiesConfiguration getClientProperties() {
......@@ -91,9 +95,7 @@ public class NegativeSSLAndKerberosTest extends BaseSSLAndKerberosTest {
}
};
// save original setting
originalConf = System.getProperty("atlas.conf");
System.setProperty("atlas.conf", persistDir);
secureEmbeddedServer = new TestSecureEmbeddedServer(21443, getWarPath()) {
@Override
public Configuration getConfiguration() {
......@@ -125,7 +127,6 @@ public class NegativeSSLAndKerberosTest extends BaseSSLAndKerberosTest {
Assert.fail("Should have failed with GSSException");
} catch(Exception e) {
e.printStackTrace();
Assert.assertTrue(e.getMessage().contains("Mechanism level: Failed to find any Kerberos tgt"));
}
}
}
......@@ -69,7 +69,7 @@ public class SSLAndKerberosTest extends BaseSSLAndKerberosTest {
// client will actually only leverage subset of these properties
final PropertiesConfiguration configuration = getSSLConfiguration(providerUrl);
configuration.setProperty("atlas.http.authentication.type", "kerberos");
TestUtils.writeConfiguration(configuration, persistDir + File.separator +
ApplicationProperties.APPLICATION_PROPERTIES);
......@@ -83,6 +83,7 @@ public class SSLAndKerberosTest extends BaseSSLAndKerberosTest {
configuration.load(url);
configuration.setProperty(TLS_ENABLED, true);
configuration.setProperty("atlas.http.authentication.enabled", "true");
configuration.setProperty("atlas.http.authentication.type", "kerberos");
configuration.setProperty("atlas.http.authentication.kerberos.principal", "HTTP/localhost@" + kdc.getRealm());
configuration.setProperty("atlas.http.authentication.kerberos.keytab", httpKeytabFile.getAbsolutePath());
configuration.setProperty("atlas.http.authentication.kerberos.name.rules",
......
......@@ -16,11 +16,12 @@
*/
package org.apache.atlas.web.security;
import java.util.Collection;
import java.util.Properties;
import org.apache.atlas.web.dao.UserDao;
import org.apache.atlas.web.model.User;
import org.junit.Assert;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.testng.annotations.Test;
......@@ -30,21 +31,27 @@ public class UserDaoTest {
public void testUserDaowithValidUserLoginAndPassword() {
Properties userLogins = new Properties();
userLogins.put("admin", "admin123");
userLogins.put("admin", "ADMIN::admin123");
UserDao user = new UserDao();
user.setUserLogins(userLogins);
User userBean = user.loadUserByUsername("admin");
Assert.assertTrue(userBean.getPassword().equals("admin123"));
Collection<? extends GrantedAuthority> authorities = userBean.getAuthorities();
String role = "";
for (GrantedAuthority gauth : authorities) {
role = gauth.getAuthority();
}
Assert.assertTrue("ADMIN".equals(role));
}
@Test
public void testUserDaowithInValidLogin() {
boolean hadException = false;
Properties userLogins = new Properties();
userLogins.put("admin", "admin123");
userLogins.put("test", "test123");
userLogins.put("admin", "ADMIN::admin123");
userLogins.put("test", "DATA_STEWARD::test123");
UserDao user = new UserDao();
user.setUserLogins(userLogins);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment