Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
aa6d87e1
Commit
aa6d87e1
authored
Jun 07, 2017
by
shiwang
Committed by
nixonrodrigues
Jun 08, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ATLAS-1804 : Allow PAM for authentication.
Signed-off-by:
nixonrodrigues
<
nixon@apache.org
>
parent
edd4aa9a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
523 additions
and
2 deletions
+523
-2
pom.xml
webapp/pom.xml
+12
-0
AtlasAuthenticationProvider.java
...pache/atlas/web/security/AtlasAuthenticationProvider.java
+16
-2
AtlasPamAuthenticationProvider.java
...he/atlas/web/security/AtlasPamAuthenticationProvider.java
+155
-0
PamLoginModule.java
...in/java/org/apache/atlas/web/security/PamLoginModule.java
+221
-0
PamPrincipal.java
...main/java/org/apache/atlas/web/security/PamPrincipal.java
+84
-0
UserAuthorityGranter.java
...a/org/apache/atlas/web/security/UserAuthorityGranter.java
+35
-0
No files found.
webapp/pom.xml
View file @
aa6d87e1
...
...
@@ -476,6 +476,18 @@
<groupId>
com.webcohesion.enunciate
</groupId>
<artifactId>
enunciate-core-annotations
</artifactId>
</dependency>
<!-- PAM -->
<dependency>
<groupId>
org.kohsuke
</groupId>
<artifactId>
libpam4j
</artifactId>
<version>
1.8
</version>
</dependency>
<dependency>
<groupId>
net.java.dev.jna
</groupId>
<artifactId>
jna
</artifactId>
<version>
4.1.0
</version>
</dependency>
</dependencies>
<build>
...
...
webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java
View file @
aa6d87e1
...
...
@@ -34,10 +34,12 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
.
getLogger
(
AtlasAuthenticationProvider
.
class
);
private
boolean
fileAuthenticationMethodEnabled
=
true
;
private
boolean
pamAuthenticationEnabled
=
false
;
private
String
ldapType
=
"NONE"
;
public
static
final
String
FILE_AUTH_METHOD
=
"atlas.authentication.method.file"
;
public
static
final
String
LDAP_AUTH_METHOD
=
"atlas.authentication.method.ldap"
;
public
static
final
String
LDAP_TYPE
=
"atlas.authentication.method.ldap.type"
;
public
static
final
String
PAM_AUTH_METHOD
=
"atlas.authentication.method.pam"
;
...
...
@@ -49,13 +51,17 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
final
AtlasADAuthenticationProvider
adAuthenticationProvider
;
final
AtlasPamAuthenticationProvider
pamAuthenticationProvider
;
@Inject
public
AtlasAuthenticationProvider
(
AtlasLdapAuthenticationProvider
ldapAuthenticationProvider
,
AtlasFileAuthenticationProvider
fileAuthenticationProvider
,
AtlasADAuthenticationProvider
adAuthenticationProvider
)
{
AtlasADAuthenticationProvider
adAuthenticationProvider
,
AtlasPamAuthenticationProvider
pamAuthenticationProvider
)
{
this
.
ldapAuthenticationProvider
=
ldapAuthenticationProvider
;
this
.
fileAuthenticationProvider
=
fileAuthenticationProvider
;
this
.
adAuthenticationProvider
=
adAuthenticationProvider
;
this
.
pamAuthenticationProvider
=
pamAuthenticationProvider
;
}
@PostConstruct
...
...
@@ -65,6 +71,8 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
this
.
fileAuthenticationMethodEnabled
=
configuration
.
getBoolean
(
FILE_AUTH_METHOD
,
true
);
this
.
pamAuthenticationEnabled
=
configuration
.
getBoolean
(
PAM_AUTH_METHOD
,
false
);
boolean
ldapAuthenticationEnabled
=
configuration
.
getBoolean
(
LDAP_AUTH_METHOD
,
false
);
if
(
ldapAuthenticationEnabled
)
{
...
...
@@ -102,13 +110,19 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
}
catch
(
Exception
ex
)
{
LOG
.
error
(
"Error while AD authentication"
,
ex
);
}
}
else
if
(
pamAuthenticationEnabled
)
{
try
{
authentication
=
pamAuthenticationProvider
.
authenticate
(
authentication
);
}
catch
(
Exception
ex
)
{
LOG
.
error
(
"Error while PAM authentication"
,
ex
);
}
}
}
if
(
authentication
!=
null
)
{
if
(
authentication
.
isAuthenticated
())
{
return
authentication
;
}
else
if
(
fileAuthenticationMethodEnabled
)
{
// If the LDAP/AD authentication fails try the local filebased login method
}
else
if
(
fileAuthenticationMethodEnabled
)
{
// If the LDAP/AD
/PAM
authentication fails try the local filebased login method
authentication
=
fileAuthenticationProvider
.
authenticate
(
authentication
);
if
(
authentication
!=
null
&&
authentication
.
isAuthenticated
())
{
...
...
webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java
0 → 100644
View file @
aa6d87e1
/*
* 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
.
web
.
security
;
import
org.apache.atlas.ApplicationProperties
;
import
org.apache.atlas.web.model.User
;
import
org.apache.commons.configuration.ConfigurationConverter
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider
;
import
org.springframework.security.authentication.jaas.memory.InMemoryConfiguration
;
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.stereotype.Component
;
import
javax.annotation.PostConstruct
;
import
javax.security.auth.login.AppConfigurationEntry
;
import
javax.security.auth.login.Configuration
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Properties
;
@Component
public
class
AtlasPamAuthenticationProvider
extends
AtlasAbstractAuthenticationProvider
{
private
static
Logger
LOG
=
LoggerFactory
.
getLogger
(
AtlasPamAuthenticationProvider
.
class
);
private
boolean
isDebugEnabled
=
LOG
.
isDebugEnabled
();
private
static
String
loginModuleName
=
"org.apache.atlas.web.security.PamLoginModule"
;
private
static
AppConfigurationEntry
.
LoginModuleControlFlag
controlFlag
=
AppConfigurationEntry
.
LoginModuleControlFlag
.
REQUIRED
;
private
Map
<
String
,
String
>
options
=
new
HashMap
<
String
,
String
>();
private
boolean
groupsFromUGI
;
private
DefaultJaasAuthenticationProvider
jaasAuthenticationProvider
=
new
DefaultJaasAuthenticationProvider
();
@PostConstruct
public
void
setup
()
{
setPamProperties
();
init
();
}
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
Authentication
auth
=
getPamAuthentication
(
authentication
);
if
(
auth
!=
null
&&
auth
.
isAuthenticated
())
{
return
auth
;
}
else
{
throw
new
AtlasAuthenticationException
(
"PAM Authentication Failed"
);
}
}
private
Authentication
getPamAuthentication
(
Authentication
authentication
)
{
if
(
isDebugEnabled
)
{
LOG
.
debug
(
"==> AtlasPamAuthenticationProvider getPamAuthentication"
);
}
try
{
String
userName
=
authentication
.
getName
();
String
userPassword
=
""
;
if
(
authentication
.
getCredentials
()
!=
null
)
{
userPassword
=
authentication
.
getCredentials
().
toString
();
}
// getting user authenticated
if
(
userName
!=
null
&&
userPassword
!=
null
&&
!
userName
.
trim
().
isEmpty
()
&&
!
userPassword
.
trim
().
isEmpty
())
{
final
List
<
GrantedAuthority
>
grantedAuths
=
getAuthorities
(
userName
);
final
UserDetails
principal
=
new
User
(
userName
,
userPassword
,
grantedAuths
);
final
Authentication
finalAuthentication
=
new
UsernamePasswordAuthenticationToken
(
principal
,
userPassword
,
grantedAuths
);
authentication
=
jaasAuthenticationProvider
.
authenticate
(
finalAuthentication
);
if
(
groupsFromUGI
)
{
authentication
=
getAuthenticationWithGrantedAuthorityFromUGI
(
authentication
);
}
else
{
authentication
=
getAuthenticationWithGrantedAuthority
(
authentication
);
}
return
authentication
;
}
else
{
return
authentication
;
}
}
catch
(
Exception
e
)
{
LOG
.
debug
(
"Pam Authentication Failed:"
,
e
);
}
if
(
isDebugEnabled
)
{
LOG
.
debug
(
"<== AtlasPamAuthenticationProvider getPamAuthentication"
);
}
return
authentication
;
}
private
void
setPamProperties
()
{
try
{
this
.
groupsFromUGI
=
ApplicationProperties
.
get
().
getBoolean
(
"atlas.authentication.method.pam.ugi-groups"
,
true
);
Properties
properties
=
ConfigurationConverter
.
getProperties
(
ApplicationProperties
.
get
()
.
subset
(
"atlas.authentication.method.pam"
));
for
(
String
key
:
properties
.
stringPropertyNames
())
{
String
value
=
properties
.
getProperty
(
key
);
options
.
put
(
key
,
value
);
}
if
(!
options
.
containsKey
(
"service"
))
{
options
.
put
(
"service"
,
"atlas-login"
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Exception while setLdapProperties"
,
e
);
}
}
private
void
init
()
{
try
{
AppConfigurationEntry
appConfigurationEntry
=
new
AppConfigurationEntry
(
loginModuleName
,
controlFlag
,
options
);
AppConfigurationEntry
[]
appConfigurationEntries
=
new
AppConfigurationEntry
[]{
appConfigurationEntry
};
Map
<
String
,
AppConfigurationEntry
[]>
appConfigurationEntriesOptions
=
new
HashMap
<
String
,
AppConfigurationEntry
[]>();
appConfigurationEntriesOptions
.
put
(
"SPRINGSECURITY"
,
appConfigurationEntries
);
Configuration
configuration
=
new
InMemoryConfiguration
(
appConfigurationEntriesOptions
);
jaasAuthenticationProvider
.
setConfiguration
(
configuration
);
UserAuthorityGranter
authorityGranter
=
new
UserAuthorityGranter
();
UserAuthorityGranter
[]
authorityGranters
=
new
UserAuthorityGranter
[]{
authorityGranter
};
jaasAuthenticationProvider
.
setAuthorityGranters
(
authorityGranters
);
jaasAuthenticationProvider
.
afterPropertiesSet
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to init PAM Authentication"
,
e
);
}
}
}
webapp/src/main/java/org/apache/atlas/web/security/PamLoginModule.java
0 → 100644
View file @
aa6d87e1
/*
* 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
.
web
.
security
;
import
org.jvnet.libpam.PAM
;
import
org.jvnet.libpam.PAMException
;
import
org.jvnet.libpam.UnixUser
;
import
javax.security.auth.Subject
;
import
javax.security.auth.callback.*
;
import
javax.security.auth.login.FailedLoginException
;
import
javax.security.auth.login.LoginException
;
import
javax.security.auth.spi.LoginModule
;
import
java.io.IOException
;
import
java.security.Principal
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
public
class
PamLoginModule
extends
Object
implements
LoginModule
{
public
static
final
String
SERVICE_KEY
=
"service"
;
private
PAM
pam
;
private
Subject
subject
;
private
CallbackHandler
callbackHandler
;
private
Map
<
String
,
?>
options
;
private
String
username
;
private
String
password
;
private
boolean
authSucceeded
;
private
PamPrincipal
principal
;
public
PamLoginModule
()
{
super
();
authSucceeded
=
false
;
}
@Override
public
void
initialize
(
Subject
subject
,
CallbackHandler
callbackHandler
,
Map
<
String
,
?>
sharedState
,
Map
<
String
,
?>
options
)
{
this
.
subject
=
subject
;
this
.
callbackHandler
=
callbackHandler
;
this
.
options
=
new
HashMap
<>(
options
);
}
@Override
public
boolean
login
()
throws
LoginException
{
initializePam
();
obtainUserAndPassword
();
return
performLogin
();
}
private
void
initializePam
()
throws
LoginException
{
String
service
=
(
String
)
options
.
get
(
SERVICE_KEY
);
if
(
service
==
null
)
{
throw
new
LoginException
(
"Error: PAM service was not defined"
);
}
createPam
(
service
);
}
private
void
createPam
(
String
service
)
throws
LoginException
{
try
{
pam
=
new
PAM
(
service
);
}
catch
(
PAMException
ex
)
{
LoginException
le
=
new
LoginException
(
"Error initializing PAM"
);
le
.
initCause
(
ex
);
throw
le
;
}
}
private
void
obtainUserAndPassword
()
throws
LoginException
{
if
(
callbackHandler
==
null
)
{
throw
new
LoginException
(
"Error: no CallbackHandler available to gather authentication information from the user"
);
}
try
{
NameCallback
nameCallback
=
new
NameCallback
(
"username"
);
PasswordCallback
passwordCallback
=
new
PasswordCallback
(
"password"
,
false
);
invokeCallbackHandler
(
nameCallback
,
passwordCallback
);
initUserName
(
nameCallback
);
initPassword
(
passwordCallback
);
}
catch
(
IOException
|
UnsupportedCallbackException
ex
)
{
LoginException
le
=
new
LoginException
(
"Error in callbacks"
);
le
.
initCause
(
ex
);
throw
le
;
}
}
private
void
invokeCallbackHandler
(
NameCallback
nameCallback
,
PasswordCallback
passwordCallback
)
throws
IOException
,
UnsupportedCallbackException
{
Callback
[]
callbacks
=
new
Callback
[
2
];
callbacks
[
0
]
=
nameCallback
;
callbacks
[
1
]
=
passwordCallback
;
callbackHandler
.
handle
(
callbacks
);
}
private
void
initUserName
(
NameCallback
nameCallback
)
{
username
=
nameCallback
.
getName
();
}
private
void
initPassword
(
PasswordCallback
passwordCallback
)
{
char
[]
password
=
passwordCallback
.
getPassword
();
if
(
password
!=
null
)
{
this
.
password
=
new
String
(
password
);
}
passwordCallback
.
clearPassword
();
}
private
boolean
performLogin
()
throws
LoginException
{
try
{
UnixUser
user
=
pam
.
authenticate
(
username
,
password
);
principal
=
new
PamPrincipal
(
user
);
authSucceeded
=
true
;
return
true
;
}
catch
(
PAMException
ex
)
{
LoginException
le
=
new
FailedLoginException
(
"Invalid username or password"
);
le
.
initCause
(
ex
);
throw
le
;
}
}
@Override
public
boolean
commit
()
throws
LoginException
{
if
(
authSucceeded
==
false
)
{
return
false
;
}
if
(
subject
.
isReadOnly
())
{
cleanup
();
throw
new
LoginException
(
"Subject is read-only"
);
}
Set
<
Principal
>
principals
=
subject
.
getPrincipals
();
if
(
principals
.
contains
(
principal
)
==
false
)
{
principals
.
add
(
principal
);
}
return
true
;
}
@Override
public
boolean
abort
()
throws
LoginException
{
if
(
authSucceeded
==
false
)
{
return
false
;
}
cleanup
();
return
true
;
}
@Override
public
boolean
logout
()
throws
LoginException
{
if
(
subject
.
isReadOnly
())
{
cleanup
();
throw
new
LoginException
(
"Subject is read-only"
);
}
subject
.
getPrincipals
().
remove
(
principal
);
cleanup
();
return
true
;
}
private
void
cleanup
()
{
authSucceeded
=
false
;
username
=
null
;
password
=
null
;
principal
=
null
;
pam
.
dispose
();
}
}
webapp/src/main/java/org/apache/atlas/web/security/PamPrincipal.java
0 → 100644
View file @
aa6d87e1
/*
* 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
.
web
.
security
;
import
org.jvnet.libpam.UnixUser
;
import
java.security.Principal
;
import
java.util.Collections
;
import
java.util.Set
;
public
class
PamPrincipal
extends
Object
implements
Principal
{
private
String
userName
;
private
String
gecos
;
private
String
homeDir
;
private
String
shell
;
private
int
uid
;
private
int
gid
;
private
Set
<
String
>
groups
;
public
PamPrincipal
(
UnixUser
user
)
{
super
();
userName
=
user
.
getUserName
();
gecos
=
user
.
getGecos
();
homeDir
=
user
.
getDir
();
shell
=
user
.
getShell
();
uid
=
user
.
getUID
();
gid
=
user
.
getGID
();
groups
=
Collections
.
unmodifiableSet
(
user
.
getGroups
());
}
@Override
public
String
getName
()
{
return
userName
;
}
public
String
getGecos
()
{
return
gecos
;
}
public
String
getHomeDir
()
{
return
homeDir
;
}
public
String
getShell
()
{
return
shell
;
}
public
int
getUid
()
{
return
uid
;
}
public
int
getGid
()
{
return
gid
;
}
public
Set
<
String
>
getGroups
()
{
return
groups
;
}
}
webapp/src/main/java/org/apache/atlas/web/security/UserAuthorityGranter.java
0 → 100644
View file @
aa6d87e1
/*
* 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
.
web
.
security
;
import
org.springframework.security.authentication.jaas.AuthorityGranter
;
import
java.security.Principal
;
import
java.util.Collections
;
import
java.util.Set
;
public
class
UserAuthorityGranter
implements
AuthorityGranter
{
@Override
public
Set
<
String
>
grant
(
Principal
principal
)
{
Collections
.
singleton
(
"DATA_SCIENTIST"
);
return
null
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment