最近在公司写内设文档, 发现用户登录时, 需要连接访问active directory服务并获取里面存储的用户数据, 进行域控处理。我, 刚出来, 看着其实挺懵的, 便马上上网查资料了。
总体来说, ldap是一种数据存储的东西, 一种树状结构的目录, 能提高检索数据的效率, active directory是微软提供的ldap服务。关于概念的部分, 当然还是需要大家的补充, 下面我将具体连接和获取数据的java代码写下来, 以供大家参(#‵′)kao。
利用JNDI技术连接Active Directory服务
首先, 你需要封装连接active directory服务的参数对象
(可以将连接参数都存放在poperties文件中, 方便修改)
server.system-info-setting.connect-host | localhost |
server.system-info-setting.connect-port | 10389 |
server.system-info-setting.security-level | simple |
server.system-info-setting.user-identification-name | cn={0}, ou=system (ldap目录结构) |
server.system-info-setting.search-filter | * |
server.system-info-setting.timeout-time | 30000 |
//创建对象名为env的Hashtable<String, String>集合
Hashtable<String, String> env = new Hashtable<>();
//设置初始化Context Factory
env.put(DirContext.INITIAL_CONTEXT_FACTORY, LDAP_CONTEXT_FACTORY);
//设置LDAP目标URL
String url = MessageFormat.format(PROVIDER_URL, host, port);
env.put(DirContext.PROVIDER_URL, url);
//设置安全级别
env.put(DirContext.SECURITY_AUTHENTICATION, level);
//设置LDAP识别名
env.put(DirContext.SECURITY_PRINCIPAL, dn);
//设置密码
env.put(DirContext.SECURITY_CREDENTIALS, password);
//设置连接等待时长
env.put("com.sun.jndi.ldap.connect.timeout", timeout);
//设置JNDI参数
env.put("com.sun.jndi.ldap.connect.pool", "true");
env.put("com.sun.jndi.connect.pool.debug", "all");
//创建实例区连接Active Directory
//dircon是DirContext类的对象
dircon = new InitialDirContext(env);
获取信息
在检索active directory服务中信息时, 可以传递dn作为用户标识去获取匹配的用户信息, 并且也能过滤相对应的字符串信息
SearchControls searchControls = new SearchControls();
//设置SearchControls的范围
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//检索用户信息
NamingEnumeration<SearchResult> result = dircon.search(dn, filter, searchControls);
if (!result.hasMore())
//MESSAGE_FAILURE_SEARCH : 检索失败
throw new Exception(MESSAGE_FAILURE_SEARCH);
//获取下一行信息
SearchResult searchResult = result.next();
//获取数据所有属性
NamingEnumeration<?> attributes = searchResult.getAttributes().getAll();
//创建一个Map对象
Map<String, Object> resultMap = new HashMap<String, Object>();
//循环遍历属性集合
while (attributes.hasMore()) {
//获取单个属性
Attribute attr = (Attribute) attributes.nextElement();
//获取单个值
Enumeration<?> values = attr.getAll();
if (values.hasMoreElements())
resultMap.put(attr.getID(), values.nextElement());
}
if (resultMap.isEmpty())
、 //MESSAGE_FAILURE_SEARCH : 检索失败
throw new Exception(MESSAGE_FAILURE_SEARCH);
//获取数据后返回Map集合
return resultMap;