📄 activedirectoryuserdatabase.java
字号:
package com.sslexplorer.activedirectory;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.URI;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Vector;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.PartialResultException;
import javax.naming.directory.Attribute;
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.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.PagedResultsControl;
import javax.naming.ldap.PagedResultsResponseControl;
import javax.security.auth.Subject;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.apache.commons.cache.Cache;
import org.apache.commons.cache.MemoryStash;
import org.apache.commons.cache.SimpleCache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sslexplorer.boot.ContextHolder;
import com.sslexplorer.boot.DefaultPropertyDefinition;
import com.sslexplorer.boot.PropertyDefinition;
import com.sslexplorer.boot.PropertyList;
import com.sslexplorer.boot.Util;
import com.sslexplorer.core.CoreEvent;
import com.sslexplorer.core.CoreJAASConfiguration;
import com.sslexplorer.core.CoreListener;
import com.sslexplorer.core.CoreServlet;
import com.sslexplorer.core.CoreUtil;
import com.sslexplorer.properties.DefaultPropertyDefinitionCategory;
import com.sslexplorer.properties.PropertyChangeEvent;
import com.sslexplorer.properties.PropertyDatabase;
import com.sslexplorer.security.DefaultUserDatabase;
import com.sslexplorer.security.InvalidLoginCredentialsException;
import com.sslexplorer.security.Role;
import com.sslexplorer.security.User;
import com.sslexplorer.security.UserDatabaseException;
import com.sslexplorer.security.UserPasswordCallbackHandler;
/**
* <p>
* Microsoft Active Directory implementation of
* {@link com.sslexplorer.security.UserDatabase}.
*
* @author Lee Painter <a href="mailto:lee@3sp.com"><lee@3sp.com></a>
* @author Brett Smith <a href="mailto:brett@3sp.com"><brett@3sp.com></a>
* @version $Revision: 1.89 $
*/
public class ActiveDirectoryUserDatabase extends DefaultUserDatabase implements CoreListener {
static String ALL_USERS = "(&(objectClass=user))";
static String USER_FILTER = "(&(objectClass=user)(sAMAccountName=%USERNAME%))";
static String GROUP_FILTER = "(&(objectClass=group)(sAMAccountName=%GROUPNAME%))";
static String USER_ATTRS[] = { "sAMAccountName", "cn", "mail", "homeDirectory", "homeDrive", "memberOf", "primaryGroupId" };
static String GROUP_ATTRS[] = { "cn", "sAMAccountName", "objectSid", "memberOf" };
static String MEMBEROF_ATTRS[] = { "cn" };
static Log log = LogFactory.getLog(ActiveDirectoryUserDatabase.class);
private List includedOUBasesList;
private List excludedOUBasesList;
private String adURL;
private PropertyList administrators;
private String domain;
private String activeDirectoryRoot;
private Cache availablePrincipalsCache;
boolean hasFilteredOUs = false;
boolean usernamesAreCaseSensitive = false;
boolean checkedNameInNameSpace = false;
Method nameInNamespaceMethod;
HashMap groupsByRID;
/**
* Constructor
*/
public ActiveDirectoryUserDatabase() {
super("Active Directory", false, false, 80);
CoreJAASConfiguration config = (CoreJAASConfiguration) Configuration.getConfiguration();
HashMap parms = new HashMap();
parms.put("client", "TRUE");
parms.put("debug", String.valueOf(log.isDebugEnabled()).toUpperCase());
parms.put("useSubjectCredsOnly", "FALSE");
parms.put("useTicketCache", "FALSE");
AppConfigurationEntry entry = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, parms);
config.addAppConfigurationEntry(getClass().getName(), entry);
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.core.Database#open(com.sslexplorer.core.CoreServlet)
*/
public void open(CoreServlet controllingServlet) throws Exception {
// TODO We eventually want to store attributes in AD itself, but for now
// our own database is cool
super.open(controllingServlet);
CoreServlet.getServlet().addCoreListener(this);
addPropertyDefinitions();
initialise();
open = true;
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.boot.Database#close()
*/
public void close() throws Exception {
super.close();
open = false;
CoreServlet.getServlet().removeCoreListener(this);
if (availablePrincipalsCache != null)
availablePrincipalsCache.clear();
removePropertyDefinitions();
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#logon(java.lang.String,
* java.lang.String)
*/
public User logon(String username, String password) throws UserDatabaseException, InvalidLoginCredentialsException {
try {
/**
* This code attempts to fix case sensitivity
*/
if (!usernamesAreCaseSensitive) {
Map map = getUserMap("*");
if (map == null) {
throw new InvalidLoginCredentialsException(
"Failed to get user list. This may be because the service account username or password is incorrect.");
}
User realUser = (User) map.get(username.toLowerCase());
if (realUser == null) {
log.warn("No username " + username + " could be found in the cached user map.");
} else {
username = realUser.getPrincipalName();
}
}
LoginContext lc = createLoginContext(username, password);
UserDetailsAction uia = new UserDetailsAction(username, password);
// Perform JNDI work as logged in subject
ActiveDirectoryUser aduser = (ActiveDirectoryUser) Subject.doAs(lc.getSubject(), uia);
aduser.setLoginContext(lc);
return aduser;
} catch (LoginException ex) {
throw new InvalidLoginCredentialsException("Invalid username or password.", ex);
}
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#logout(com.sslexplorer.security.User)
*/
public void logout(User user) {
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#getUsersInRole(com.sslexplorer.security.Role)
*/
public User[] getUsersInRole(Role role) throws Exception {
return CoreUtil.getUsersInRole(role, this);
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#listAllUsers(java.lang.String)
*/
public User[] listAllUsers(String filter) throws Exception {
if (log.isDebugEnabled())
log.debug("List all users with filter '" + filter + "'");
return mapToUserArray(getUserMap(filter));
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#getAccount(java.lang.String)
*/
public User getAccount(String username) throws Exception {
if (log.isDebugEnabled())
log.debug("Getting account " + username);
User u = (User) getUserMap("*").get(usernamesAreCaseSensitive ? username : username.toLowerCase());
if (u == null) {
throw new Exception(username + " is not a valid user!");
}
return u;
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#getRole(java.lang.String)
*/
public Role getRole(String rolename) throws Exception {
Role r = (Role) getRoleMap("*").getByGroupName(rolename);
if (r == null) {
throw new Exception(rolename + " is not a valid role!");
}
return r;
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#listAllRoles(java.lang.String)
*/
public Role[] listAllRoles(String filter) throws UserDatabaseException {
if (log.isDebugEnabled())
log.debug("List all roles with filter '" + filter + "'");
return mapToRoleArray(getRoleMap(filter));
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#checkPassword(java.lang.String,
* java.lang.String)
*/
public boolean checkPassword(String username, String password) throws UserDatabaseException, InvalidLoginCredentialsException {
try {
createLoginContext(username, password);
return true;
} catch (LoginException ex) {
}
return false;
}
/*
* (non-Javadoc)
*
* @see com.sslexplorer.security.UserDatabase#listAvailablePrincipals()
*/
public com.sslexplorer.policyframework.Principal[] listAvailablePrincipals() throws Exception {
if (log.isDebugEnabled())
log.debug("Listing available principals");
return listAllUsers("*");
}
/**
* Get if a user is the default administrator.
*
* @param principal
* @return is default adminstrator
* @throws Exception on any error
*/
public boolean isDefaultAdministrator(com.sslexplorer.policyframework.Principal principal) throws Exception {
boolean found = false;
// Check based on name
for (Iterator j = administrators.iterator(); !found && j.hasNext();) {
found = principal.getPrincipalName().matches((String) j.next());
}
// Check based on roles
if (principal instanceof User) {
ActiveDirectoryUser adUser = (ActiveDirectoryUser) principal;
if (adUser.getRoles() != null) {
for (int i = 0; !found && i < adUser.getRoles().length; i++) {
for (Iterator j = administrators.iterator(); !found && j.hasNext();) {
String admin = (String) j.next();
ActiveDirectoryGroup ag = (ActiveDirectoryGroup) adUser.getRoles()[i];
if (ag != null && ag.getSAMAccountName() != null) {
found = ag.getSAMAccountName().matches(admin);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -