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
8 years ago
by
shiwang
Committed by
nixonrodrigues
8 years ago
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
Show 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>
...
...
This diff is collapsed.
Click to expand it.
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
())
{
...
...
This diff is collapsed.
Click to expand it.
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
);
}
}
}
This diff is collapsed.
Click to expand it.
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
();
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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
;
}
}
This diff is collapsed.
Click to expand it.
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