[New] added config for privilege handler, add ldap handler
This commit is contained in:
parent
3ccfc3e942
commit
6deafccb33
|
@ -1255,7 +1255,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
* @throws InvalidCredentialsException
|
* @throws InvalidCredentialsException
|
||||||
* if the given credentials are invalid, the user does not exist, or has no password set
|
* if the given credentials are invalid, the user does not exist, or has no password set
|
||||||
*/
|
*/
|
||||||
private synchronized User checkCredentialsAndUserState(String username, char[] password)
|
protected synchronized User checkCredentialsAndUserState(String username, char[] password)
|
||||||
throws InvalidCredentialsException, AccessDeniedException {
|
throws InvalidCredentialsException, AccessDeniedException {
|
||||||
|
|
||||||
// and validate the password
|
// and validate the password
|
||||||
|
@ -1519,7 +1519,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the concrete {@link EncryptionHandler}. The passed parameter map contains any configuration this
|
* Initializes the concrete {@link PrivilegeHandler}. The passed parameter map contains any configuration this
|
||||||
* {@link PrivilegeHandler} might need. This method may only be called once and this must be enforced by the
|
* {@link PrivilegeHandler} might need. This method may only be called once and this must be enforced by the
|
||||||
* concrete implementation
|
* concrete implementation
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
package li.strolch.privilege.handler;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.NamingEnumeration;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import javax.naming.directory.SearchControls;
|
||||||
|
import javax.naming.directory.SearchResult;
|
||||||
|
import javax.naming.ldap.LdapName;
|
||||||
|
import javax.naming.ldap.Rdn;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import li.strolch.privilege.base.AccessDeniedException;
|
||||||
|
import li.strolch.privilege.base.InvalidCredentialsException;
|
||||||
|
import li.strolch.privilege.model.UserState;
|
||||||
|
import li.strolch.privilege.model.internal.User;
|
||||||
|
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||||
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
|
||||||
|
public class LdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
||||||
|
|
||||||
|
protected static final Logger logger = LoggerFactory.getLogger(LdapPrivilegeHandler.class);
|
||||||
|
|
||||||
|
private Map<String, Set<String>> rolesForLdapGroups;
|
||||||
|
private String providerUrl;
|
||||||
|
private String searchBase;
|
||||||
|
private String location;
|
||||||
|
private String domain;
|
||||||
|
private String adminUsers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void initialize(Map<String, String> parameterMap, EncryptionHandler encryptionHandler,
|
||||||
|
PersistenceHandler persistenceHandler, UserChallengeHandler userChallengeHandler,
|
||||||
|
SingleSignOnHandler ssoHandler, Map<String, Class<PrivilegePolicy>> policyMap) {
|
||||||
|
|
||||||
|
rolesForLdapGroups = getLdapGroupToRolesMappingFromConfig(parameterMap);
|
||||||
|
|
||||||
|
this.providerUrl = parameterMap.get("providerUrl");
|
||||||
|
this.searchBase = parameterMap.get("searchBase");
|
||||||
|
this.location = parameterMap.get("location");
|
||||||
|
this.domain = parameterMap.get("domain");
|
||||||
|
this.adminUsers = parameterMap.get("adminUsers");
|
||||||
|
|
||||||
|
super.initialize(parameterMap, encryptionHandler, persistenceHandler, userChallengeHandler, ssoHandler,
|
||||||
|
policyMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized User checkCredentialsAndUserState(String username, char[] password)
|
||||||
|
throws InvalidCredentialsException, AccessDeniedException {
|
||||||
|
// Set up the environment for creating the initial context
|
||||||
|
Hashtable<String, String> env = new Hashtable<>();
|
||||||
|
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
env.put(Context.PROVIDER_URL, providerUrl);
|
||||||
|
|
||||||
|
// Authenticate
|
||||||
|
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||||
|
env.put(Context.SECURITY_PRINCIPAL, username + domain);
|
||||||
|
env.put(Context.SECURITY_CREDENTIALS, new String(password));
|
||||||
|
|
||||||
|
logger.info("User {} tries to login on ldap", username + domain);
|
||||||
|
|
||||||
|
String memberOfLdapString = "";
|
||||||
|
Set<String> strolchRoles = new HashSet<>();
|
||||||
|
|
||||||
|
// Create the initial context
|
||||||
|
try {
|
||||||
|
DirContext ctx = new InitialDirContext(env);
|
||||||
|
|
||||||
|
//Create the search controls
|
||||||
|
SearchControls searchCtls = new SearchControls();
|
||||||
|
|
||||||
|
//Specify the search scope
|
||||||
|
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||||
|
|
||||||
|
String searchFilter = "(&(objectCategory=person)(objectClass=user)(userPrincipalName=" + username + domain
|
||||||
|
+ "))";
|
||||||
|
|
||||||
|
// Search for objects using the filter
|
||||||
|
NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);
|
||||||
|
|
||||||
|
//Loop through the search results
|
||||||
|
while (answer.hasMoreElements()) {
|
||||||
|
SearchResult sr = (SearchResult) answer.next();
|
||||||
|
|
||||||
|
Attributes attrs = sr.getAttributes();
|
||||||
|
memberOfLdapString = (attrs.get("memberOf") != null) ? attrs.get("memberOf").get().toString() : "";
|
||||||
|
|
||||||
|
// extract group name from ldap string -> CN=groupname,OU=company,DC=domain,DC=country
|
||||||
|
LdapName memberOfName = new LdapName(memberOfLdapString);
|
||||||
|
for (Rdn rdn : memberOfName.getRdns()) {
|
||||||
|
if (rdn.getType().equalsIgnoreCase("CN")) {
|
||||||
|
String groupName = rdn.getValue().toString();
|
||||||
|
Set<String> foundStrolchRoles = rolesForLdapGroups.get(groupName);
|
||||||
|
if (foundStrolchRoles != null)
|
||||||
|
strolchRoles.addAll(foundStrolchRoles);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("User " + username + " is member of groups: " + memberOfLdapString);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.close();
|
||||||
|
} catch (NamingException e) {
|
||||||
|
throw new AccessDeniedException("Could not login with user: " + username + domain + " on Ldap");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> properties = new HashMap<>();
|
||||||
|
|
||||||
|
// this must be changed, because the location param must be taken from the logged in person
|
||||||
|
properties.put("location", location);
|
||||||
|
|
||||||
|
if (adminUsers.contains(username)) {
|
||||||
|
strolchRoles = rolesForLdapGroups.get("admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new User(username, username, null, null, null, -1, -1, username, username, UserState.ENABLED,
|
||||||
|
strolchRoles, Locale.GERMAN, properties);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Set<String>> getLdapGroupToRolesMappingFromConfig(Map<String, String> params) {
|
||||||
|
Map<String, Set<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
String rolesForLdapGroups = params.get("rolesForLdapGroups");
|
||||||
|
|
||||||
|
DBC.PRE.assertNotEmpty("No roles mapping for ldap directory groups defined (param: rolesForLdapGroups)",
|
||||||
|
rolesForLdapGroups);
|
||||||
|
|
||||||
|
// rolesForLdapGroups = admin=StrolchAdmin,UserPrivileges;user=UserPrivileges
|
||||||
|
String[] ldapGroupRoles = rolesForLdapGroups.split(";");
|
||||||
|
|
||||||
|
for (String ldapGroupRole : ldapGroupRoles) {
|
||||||
|
// admin=StrolchAdmin,UserPrivileges
|
||||||
|
String[] splittedGroupRoles = ldapGroupRole.split("=");
|
||||||
|
String ldapGroupName = splittedGroupRoles[0];
|
||||||
|
// StrolchAdmin,UserPrivileges
|
||||||
|
Set<String> roleNames = new HashSet<>(Arrays.asList(splittedGroupRoles[1].split(",")));
|
||||||
|
|
||||||
|
result.put(ldapGroupName, roleNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,7 +22,12 @@ import java.text.MessageFormat;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
import li.strolch.privilege.handler.*;
|
import li.strolch.privilege.handler.DefaultPrivilegeHandler;
|
||||||
|
import li.strolch.privilege.handler.EncryptionHandler;
|
||||||
|
import li.strolch.privilege.handler.PersistenceHandler;
|
||||||
|
import li.strolch.privilege.handler.PrivilegeHandler;
|
||||||
|
import li.strolch.privilege.handler.SingleSignOnHandler;
|
||||||
|
import li.strolch.privilege.handler.UserChallengeHandler;
|
||||||
import li.strolch.privilege.model.internal.PrivilegeContainerModel;
|
import li.strolch.privilege.model.internal.PrivilegeContainerModel;
|
||||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||||
import li.strolch.privilege.xml.PrivilegeConfigSaxReader;
|
import li.strolch.privilege.xml.PrivilegeConfigSaxReader;
|
||||||
|
@ -151,8 +156,17 @@ public class PrivilegeInitializationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize privilege handler
|
// initialize privilege handler
|
||||||
DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler();
|
DefaultPrivilegeHandler privilegeHandler;
|
||||||
parameterMap = containerModel.getParameterMap();
|
parameterMap = containerModel.getParameterMap();
|
||||||
|
|
||||||
|
if (containerModel.getPrivilegeHandlerClassName() == null) {
|
||||||
|
privilegeHandler = new DefaultPrivilegeHandler();
|
||||||
|
} else {
|
||||||
|
String privilegeHandlerClassName = containerModel.getPrivilegeHandlerClassName();
|
||||||
|
privilegeHandler = ClassHelper.instantiateClass(privilegeHandlerClassName);
|
||||||
|
parameterMap.putAll(containerModel.getPrivilegeHandlerParameterMap());
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Class<PrivilegePolicy>> policyMap = containerModel.getPolicies();
|
Map<String, Class<PrivilegePolicy>> policyMap = containerModel.getPolicies();
|
||||||
try {
|
try {
|
||||||
privilegeHandler
|
privilegeHandler
|
||||||
|
|
|
@ -40,11 +40,13 @@ public class PrivilegeContainerModel {
|
||||||
private String persistenceHandlerClassName;
|
private String persistenceHandlerClassName;
|
||||||
private String userChallengeHandlerClassName;
|
private String userChallengeHandlerClassName;
|
||||||
private String ssoHandlerClassName;
|
private String ssoHandlerClassName;
|
||||||
|
private String privilegeHandlerClassName;
|
||||||
|
|
||||||
private Map<String, String> encryptionHandlerParameterMap;
|
private Map<String, String> encryptionHandlerParameterMap;
|
||||||
private Map<String, String> persistenceHandlerParameterMap;
|
private Map<String, String> persistenceHandlerParameterMap;
|
||||||
private Map<String, String> challengeHandlerParameterMap;
|
private Map<String, String> challengeHandlerParameterMap;
|
||||||
private Map<String, String> ssoHandlerParameterMap;
|
private Map<String, String> ssoHandlerParameterMap;
|
||||||
|
private Map<String, String> privilegeHandlerParameterMap;
|
||||||
|
|
||||||
private Map<String, String> parameterMap;
|
private Map<String, String> parameterMap;
|
||||||
|
|
||||||
|
@ -56,6 +58,7 @@ public class PrivilegeContainerModel {
|
||||||
this.persistenceHandlerParameterMap = new HashMap<>();
|
this.persistenceHandlerParameterMap = new HashMap<>();
|
||||||
this.challengeHandlerParameterMap = new HashMap<>();
|
this.challengeHandlerParameterMap = new HashMap<>();
|
||||||
this.ssoHandlerParameterMap = new HashMap<>();
|
this.ssoHandlerParameterMap = new HashMap<>();
|
||||||
|
this.privilegeHandlerParameterMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getParameterMap() {
|
public Map<String, String> getParameterMap() {
|
||||||
|
@ -114,6 +117,14 @@ public class PrivilegeContainerModel {
|
||||||
this.ssoHandlerClassName = ssoHandlerClassName;
|
this.ssoHandlerClassName = ssoHandlerClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPrivilegeHandlerClassName() {
|
||||||
|
return this.privilegeHandlerClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivilegeHandlerClassName(String privilegeHandlerClassName) {
|
||||||
|
this.privilegeHandlerClassName = privilegeHandlerClassName;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, String> getUserChallengeHandlerParameterMap() {
|
public Map<String, String> getUserChallengeHandlerParameterMap() {
|
||||||
return this.challengeHandlerParameterMap;
|
return this.challengeHandlerParameterMap;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +141,14 @@ public class PrivilegeContainerModel {
|
||||||
this.ssoHandlerParameterMap = ssoHandlerParameterMap;
|
this.ssoHandlerParameterMap = ssoHandlerParameterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getPrivilegeHandlerParameterMap() {
|
||||||
|
return this.privilegeHandlerParameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivilegeHandlerParameterMap(Map<String, String> privilegeHandlerParameterMap) {
|
||||||
|
this.privilegeHandlerParameterMap = privilegeHandlerParameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
public void addPolicy(String privilegeName, String policyClassName) {
|
public void addPolicy(String privilegeName, String policyClassName) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -181,6 +200,8 @@ public class PrivilegeContainerModel {
|
||||||
builder.append(this.challengeHandlerParameterMap.size());
|
builder.append(this.challengeHandlerParameterMap.size());
|
||||||
builder.append(", ssoHandlerParameterMap=");
|
builder.append(", ssoHandlerParameterMap=");
|
||||||
builder.append(this.ssoHandlerParameterMap.size());
|
builder.append(this.ssoHandlerParameterMap.size());
|
||||||
|
builder.append(", privilegeHandlerParameterMap=");
|
||||||
|
builder.append(this.privilegeHandlerParameterMap.size());
|
||||||
builder.append(", parameterMap=");
|
builder.append(", parameterMap=");
|
||||||
builder.append(this.parameterMap.size());
|
builder.append(this.parameterMap.size());
|
||||||
builder.append(", policies=");
|
builder.append(", policies=");
|
||||||
|
|
|
@ -89,6 +89,15 @@ public class PrivilegeConfigDomWriter {
|
||||||
fillParameterMap(doc, ssoHandlerElem, this.containerModel.getSsoHandlerParameterMap());
|
fillParameterMap(doc, ssoHandlerElem, this.containerModel.getSsoHandlerParameterMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create PrivilegeHandler
|
||||||
|
if (this.containerModel.getSsoHandlerClassName() != null) {
|
||||||
|
Element privilegeHandlerElem = doc.createElement(XML_HANDLER_PRIVILEGE);
|
||||||
|
containerElement.appendChild(privilegeHandlerElem);
|
||||||
|
privilegeHandlerElem.setAttribute(XML_ATTR_CLASS, this.containerModel.getPrivilegeHandlerClassName());
|
||||||
|
// Parameters
|
||||||
|
fillParameterMap(doc, privilegeHandlerElem, this.containerModel.getPrivilegeHandlerParameterMap());
|
||||||
|
}
|
||||||
|
|
||||||
// Policies
|
// Policies
|
||||||
Element policiesElem = doc.createElement(XML_POLICIES);
|
Element policiesElem = doc.createElement(XML_POLICIES);
|
||||||
rootElement.appendChild(policiesElem);
|
rootElement.appendChild(policiesElem);
|
||||||
|
|
|
@ -109,6 +109,10 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
||||||
this.currentElement = qName;
|
this.currentElement = qName;
|
||||||
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
|
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
|
||||||
getContainerModel().setSsoHandlerClassName(className);
|
getContainerModel().setSsoHandlerClassName(className);
|
||||||
|
} else if (qName.equals(XmlConstants.XML_HANDLER_PRIVILEGE)) {
|
||||||
|
this.currentElement = qName;
|
||||||
|
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
|
||||||
|
getContainerModel().setPrivilegeHandlerClassName(className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +133,8 @@ public class PrivilegeConfigSaxReader extends DefaultHandler {
|
||||||
getContainerModel().setUserChallengeHandlerParameterMap(parametersChild.getParameterMap());
|
getContainerModel().setUserChallengeHandlerParameterMap(parametersChild.getParameterMap());
|
||||||
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_SSO)) {
|
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_SSO)) {
|
||||||
getContainerModel().setSsoHandlerParameterMap(parametersChild.getParameterMap());
|
getContainerModel().setSsoHandlerParameterMap(parametersChild.getParameterMap());
|
||||||
|
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_PRIVILEGE)) {
|
||||||
|
getContainerModel().setPrivilegeHandlerParameterMap(parametersChild.getParameterMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue