网上通过ldap操作AD的例子很多,我也是通过网络搜索然后成功的搜索了公司未知结构的AD,中间经历了一些波折,下面总结一下过程,我相信对需要操作AD的码工码农们多多少少是有些帮助。
1 获取DirContext要注意的地方。
以下是构造DirContext的基本代码:
DirContext ctx = null;
String ldapURL = "ldap://10.0.15.1:389";
String user = "test@xxx.com";
String password = "restart#123";
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.PROVIDER_URL, ldapURL);
env.put(Context.SECURITY_PRINCIPAL, user);
env.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialDirContext(env);
(1) 对AD结构是未知的情况下,ldapURL的写法保守一点比较好,所以不在端口后加DN。
(2) 为什么不用域名,而用IP,因为有时候通过域名访问不到AD,存在不稳定情况,获取域地址方法,通过cmd输入ipconfig -all找到win server既是所需ip,可能会存在多个,一般大点的公司会有多个域控制器。
(3)用户名的写法,不能直接用用户名,而要加上域信息,如userid@domain address或domain address\userid方式,如test@xxx.com,test是域帐号,xxx.com为AD域名,否则会报异常。
2 查询要注意的地方。
因为AD结构未知,所以查询仍然要保守点。
DirContext cnt = null;
try
{
cnt = this.getContext();
String base = "dc=xxx,dc=com";
String filter = "(&(objectClass=user)(sAMAccountName=*test*))";
int limitsize = 1;
SearchControls searchCons = new SearchControls();
NamingEnumeration namingEnum = null;
searchCons.setSearchScope(2);
searchCons.setCountLimit(limitsize);
searchCons.setTimeLimit(0);
namingEnum = cnt.search(base, filter, searchCons);
print(namingEnum, base, limitsize);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (cnt != null)
{
cnt.close();
}
}
(1) 未知AD情况下base开始只写出dc,因为域帐号通常不会直接建立在user节点下,一般会自己建立组织。
(2) 过滤器条件越少越好,而且最好用模糊匹配,如String filter = sAMAccountName=*test*",其中test为登录帐号名。
(3)searchCons.setSearchScope(2),设为2会查询子节点。
(4) searchCons.setTimeLimit(0),设超时时间为0标识没有超时限制。
(5)因为过滤条件比较简单而且是模糊条件,此时基本上能查出想要的数据,但节点数量很大的话查询会比较慢,此时可以根据查询的结果信息来补充DN和filter,如在DN中加入OU根,在filter加上多个条件,filter加多个条件的方法(&(条件1)(条件2))。
(6)searchCons.setCountLimit(limitsize)问题,有时查询时会报limitsize的异常,这是在遍历查询结果时出现的问题,下面是遍历的部分代码:
while (namingEnum != null && namingEnum.hasMore())
可以手工设置一个limitsize,当while循环次数到达limitsize时跳出while循环。
(7)注意关闭DirContext
3 遍历结果要注意的问题。
(1) 时间的处理
private String getConvertTime(Object time)
{
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (time == null || "".equalsIgnoreCase(time.toString().trim()))
{
return "";
}
String strTime = time.toString().trim();
if (strTime.indexOf(".") != -1)
{
strTime = strTime.substring(0, strTime.indexOf("."));
}
long longTime = Long.valueOf(strTime);
GregorianCalendar Win32Epoch = new GregorianCalendar(1601, Calendar.JANUARY, 1);
Win32Epoch.setTimeZone(TimeZone.getTimeZone("China"));
Date Win32EpochDate = Win32Epoch.getTime();
long TimeSinceWin32Epoch = longTime / 10000 + Win32EpochDate.getTime();
Date lastLogon = new Date(TimeSinceWin32Epoch);
return sf.format(lastLogon);
}
这个时间是基于格林威治1601年1月1日的,这要处理两个问题,a:加上1601年1月1日这个基础时间-Win32EpochDate.getTime(),b:格林威治时间与你所在时区有偏移量(Win32Epoch.setTimeZone(TimeZone.getTimeZone("China"));
),所以要加减偏移量才是真正的时间。
(2) lastLogon与lastLogonTimestamp,其中lastLogon至少在一台AD上是实时更新的,而lastLogonTimestamp则不是通常半个月才会更新,lastLogon因为存在在不同AD上的同步问题,所以需要在所有AD上都找到lastLogon,并找出最大值才是最后的登录时间。
(3)id类的处理,id属性值是一串二进制数据,需要进行转换字符串。
private static String getGUID(byte[] inArr)
{
StringBuffer guid = new StringBuffer();
for (int i = 0; i < inArr.length; i++)
{
StringBuffer dblByte = new StringBuffer(Integer.toHexString(inArr[i] & 0xff));
if (dblByte.length() == 1)
{
guid.append("0");
}
guid.append(dblByte);
}
return guid.toString();
}
分享到:
相关推荐
通过Python,基于ldap3来实现操作AD域控,账户信息获取、解锁账户、禁用账户、启用账户、重置密码等功能。
LDAP实现AD域账号验证
Extjs实现的对Ldap的树状结构的显示,结构有点类似Softerra LDAP;一个测试类。 pdf:spring-ldap-reference.pdf Extjs.pdf 非常好的一本关于Extjs的书。 由于这些我也是才入门的时候写的,进行测试等用的,所以...
java使用ldap修改ad域用户密码
Springboot-LDAP针对AD域控做用户和组织进行同步
Adldap2, 用于人类的PHP LDAP包 Adldap2 使用LDAP不需要硬处理。Adldap2是一个经过测试的PHP包,它使用 Active Record Pattern 提供LDAP身份验证和目录管理工具。索引快速入门配置文件连接认证查
用于数据同步,将实现与企业LDAP或微软AD系统目录同步功能.
基于SSL的ldap安全访问AD认证,对密码进行加密认证!
主要介绍了JAVA使用Ldap操作AD域的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Given the varied nature of organisations and sites, adLDAP may not be _your_ complete solution, but it should be a very sound starting point. LDAP isn't overly friendly on first glance, and it's a ...
ad域,如何自动配置outlook账号和服务器地址,ldap通信目录
通过lua轻松使用ldap,附带一个IBM的ICU的lua包装,用于处理各种字符格式(由于通过ldap获得的属性有很多是utf-8格式, 用ICU的convert办法来转成ASCII非常方便). 轻松搞定AD日常管理.
使用JAVA创建AD/LDAP账号
博文链接:https://balaschen.iteye.com/blog/88178
Laravel开发-adldap2-laravel 用于Laravel 5的ADLDAP2。
Windows Server 2008 R2 AD DS架构-第05部分 Kerberos及LDAP协议
JAVA ldap AD 域 免证书 查询 修改 删除 新增 启用 禁用 修改密码
ldap 示例 博文链接:https://laowood.iteye.com/blog/168790