当前位置:首页 > 电脑知识 > 正文内容

LDAP和AD域的介绍及使用

影子1周前 (01-09)电脑知识53

1 LDAP入门
1.1 定义
LDAP是轻量目录访问协议(LightweightDirectory Access Protocol)的缩写,LDAP标准实际上是在X.500标准基础上产生的一个简化版本。
1.2 目录结构
LDAP也可以说成是一种数据库,也有client端和server端。server端是用来存放数据,client端用于操作增删改查等操作,通常说的LDAP是指运行这个数据库的服务器。只不过,LDAP数据库结构为树结构,数据存储在叶子节点上。
假设你要树上的一个苹果(一条记录),你怎么告诉园丁它的位置呢?
当然首先要说明是哪一棵树(dc,相当于MYSQL的DB),然后是从树根到那个苹果所经过的所有“分叉”(ou),最后就是这个苹果的名字(uid,相当于MySQL表主键id)。好了!这时我们可以清晰的指明这个苹果的位置了,就是那棵“歪脖树”的东边那个分叉上的靠西边那个分叉的再靠北边的分叉上的半红半绿的……
因此,在LDAP中,位置可以描述如下
树(dc=ljheee)
分叉(ou=bei,ou=xi,ou= dong)
苹果(cn=redApple)
因此,苹果redApple的位置为
dn:cn=honglv,ou=bei,ou=xi,ou=dong,dc=ljheee
dn标识一条记录,描述了数据的详细路径。因此,LDAP树形数据库如下
dn(Distinguished Name):一条记录的详细位置
dc :一条记录所属区域 (哪一颗树)
ou(Organization Unit) :一条记录所属组织 (哪一个分支)
cn/uid:一条记录的名字/ID (哪一个苹果名字) LDAP目录树的最顶部就是根,也就是所谓的“基准DN"
因此,LDAP树形结构在存储大量数据时,查询效率更高,实现迅速查找,可以应用于域验证等。
1.3 命名格式
LDAP协议中采用的命名格式常用的有如下两种:LDAP URL 和X.500。
任何一个支持LDAP 的客户都可以利用LDAP名通过LDAP协议访问活动目录,LDAP名不像普通的Internet URL名字那么直观,但是LDAP名往往隐藏在应用系统的内部,最终用户很少直接使用LDAP 名。LDAP 名使用X.500 命名规 范,也称为属性化命名法,包括活动目录服务所在的服务器以及对象的属性信息。


2 AD入门
2.1 AD定义
AD是Active Directory的缩写,AD是LDAP的一个应用实例,而不应该是LDAP本身。比如:windows域控的用户、权限管理应该是微软公司使用LDAP存储了一些数据来解决域控这个具体问题,只是AD顺便还提供了用户接口,也可以利用ActiveDirectory当做LDAP服务器存放一些自己的东西而已。比如LDAP是关系型数据库,微软自己在库中建立了几个表,每个表都定义好了字段。显然这些表和字段都是根据微软自己的需求定制的,而不是LDAP协议的规定。然后微软将LDAP做了一些封装接口,用户可以利用这些接口写程序操作LDAP,使得ActiveDirectory也成了一个LDAP服务器。
2.2 作用
2.2.1 用户服务
管理用户的域账号、用户信息、企业通信录(与电子邮箱系统集成)、用户组管理、用户身份认证、用户授权管理、按需实施组管理策略等。这里不单单指某些线上的应用更多的是指真实的计算机,服务器等。
2.2.2 计算机管理
管理服务器及客户端计算机账户、所有服务器及客户端计算机加入域管理并按需实施组策略。
2.2.3 资源管理
管理打印机、文件共享服务、网络资源等实施组策略。
2.2.4 应用系统的支持
对于电子邮件(Exchange)、在线及时通讯(Lync)、企业信息管理(SharePoint)、微软CRM&ERP等业务系统提供数据认证(身份认证、数据集成、组织规则等)。这里不单是微软产品的集成,其它的业务系统根据公用接口的方式一样可以嵌入进来。
2.2.5 客户端桌面管理
系统管理员可以集中的配置各种桌面配置策略,如:用户适用域中资源权限限制、界面功能的限制、应用程序执行特征的限制、网络连接限制、安全配置限制等。
2.3 AD域结构常用对象
2.3.1 域(Domain)
域是AD的根,是AD的管理单位。域中包含着大量的域对象,如:组织单位(Organizational Unit),组(Group),用户(User),计算机(Computer),联系人(Contact),打印机,安全策略等。
可简单理解为:公司总部。
2.3.2 组织单位(Organization Unit)
组织单位简称为OU是一个容器对象,可以把域中的对象组织成逻辑组,帮助网络管理员简化管理组。组织单位可以包含下列类型的对象:用户,计算机,工作组,打印机,安全策略,其他组织单位等。可以在组织单位基础上部署组策略,统一管理组织单位中的域对象。
可以简单理解为:分公司。
2.3.3 群组(Group)
群组是一批具有相同管理任务的用户账户,计算机账户或者其他域对象的一个集合。例如公司的开发组,产品组,运维组等等。可以简单理解为分公司的某事业部。
群组类型分为两类:
安全组:用来设置有安全权限相关任务的用户或者计算机账户的集合。比如:Tiger组都可以登录并访问某ftp地址,并拿到某个文件。
通信组:用于用户之间通信的组,适用通信组可以向一组用户发送电子邮件。比如:我要向团队内10位成员都发送同一封邮件这里就要抄送9次,而使用组的话我直接可以发送给@Tiger,所有Tiger组内的成员都会收到邮件。
2.3.4 用户(User)
AD中域用户是最小的管理单位,域用户最容易管理又最难管理,如果赋予域用户的权限过大,将带来安全隐患,如果权限过小域用户无法正常工作。可简单理解成为某个工作人员。
域用户的类型,域中常见用户类型分为:
普通域用户:创建的域用户默认就添加到"Domain Users"中。域管理员:普通域用户添加进"Domain Admins"中,其权限升为域管理员。企业管理员:普通域管理员添加进"Enterprise Admins"后,其权限提升为企业管理员,企业管理员具有最高权限。
一个大致的AD如下所示:


LDAP和AD域的介绍及使用 第1张
总之:Active Directory =LDAP服务器+LDAP应用(Windows域控)。ActiveDirectory先实现一个LDAP服务器,然后自己先用这个LDAP服务器实现了自己的一个具体应用(域控)。


3 使用LDAP操作AD域
特别注意:Java操作查询域用户信息获取到的数据和域管理员在电脑上操作查询的数据可能会存在差异(同一个意思的表示字段,两者可能不同)。
连接ad域有两个地址:LDAP://XXXXX.com:389 和 ldap://XXXXX.com:636(SSL)。
端口389用于一般的连接,例如登录,查询等非密码操作,端口636安全性较高,用户密码相关操作,例如修改密码等。
域控可能有多台服务器,之间数据同步不及时,可能会导致已经修改的数据被覆盖掉,这个要么域控缩短同步的时间差,要么同时修改每一台服务器的数据。
3.1 389登录


// 只要不抛出异常就是验证通过
public LdapContext adLogin(JSONObject json) {
String username = json.getString("username");
String password = json.getString("password");
String server = "ldap://XXXXXXX.com:389";
try {
Hashtable<String, String> env = new Hashtable<String, String>();
//用户名称,cn,ou,dc 分别:用户,组,域
env.put(Context.SECURITY_PRINCIPAL, username);
//用户密码 cn 的密码
env.put(Context.SECURITY_CREDENTIALS, password);
//url 格式:协议://ip:端口/组,域 ,直接连接到域或者组上面
env.put(Context.PROVIDER_URL, server);
//LDAP 工厂
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//验证的类型 "none", "simple", "strong"
env.put(Context.SECURITY_AUTHENTICATION, "simple");
LdapContext ldapContext = new InitialLdapContext(env, null);
log.info("ldapContext:" + ldapContext);
log.info("用户" + username + "登录验证成功");
return ldapContext;
} catch (NamingException e) {
log.info("用户" + username + "登录验证失败");
log.info("错误信息:"+e.getExplanation());
return null;
}
}
3.2 636登录验证(需要导入证书)

//证书提前倒入的Java库中
// 参考:https://www.cnblogs.com/moonson/p/4454159.html
LdapContext adLoginSSL(JSONObject json) {
String username = json.getString("username");
String password = json.getString("password");
Hashtable env = new Hashtable();
String javaHome = System.getProperty("java.home");
String keystore = javaHome+"/lib/security/cacerts";
log.info("java.home,{}",keystore);
    // 加载导入jdk的域证书
System.setProperty("javax.net.ssl.trustStore", keystore);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
String LDAP_URL = "ldap://XXXXXX.com:636"; // LDAP访问地址
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PROTOCOL, "ssl");//链接认证服务器
env.put(Context.PROVIDER_URL, LDAP_URL);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
try {
LdapContext ldapContext = new InitialLdapContext(env, null);
log.info("认证成功");// 这里可以改成异常抛出。
return ldapContext;
} catch (javax.naming.AuthenticationException e) {
log.info("认证失败:{}",e.getMessage());
} catch (Exception e) {
log.info("认证出错:{}",e.getMessage());
}
return null;
}
3.3 查询域用户信息

public List getUserKey(JSONObject json){
JSONObject admin = new JSONObject();
admin.put("username","Aaaaa");
admin.put("password", "bbbbbbbb");
String name = json.getString("name");
log.info("需要查询的ad信息:{}",name);
List<JSONObject> resultList = new JSONArray();
LdapContext ldapContext = adLogin(admin); //连接到域控
if (ldapContext!=null){
String company = "";
String result = "";
try {
// 域节点
String searchBase = "DC=XXXXXXX,DC=com";
// LDAP搜索过滤器类
//cn=*name*模糊查询
         //cn=name 精确查询
          // String searchFilter = "(objectClass="+type+")";
String searchFilter = "(sAMAccountName="+name+")"; //查询域帐号
// 创建搜索控制器
SearchControls searchCtls = new SearchControls();
String returnedAtts[]={"description","sAMAccountName","userAccountControl"};
searchCtls.setReturningAttributes(returnedAtts); //设置指定返回的字段,不设置则返回全部
// 设置搜索范围 深度
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
NamingEnumeration answer = ldapContext.search(searchBase, searchFilter,searchCtls);
// 初始化搜索结果数为0
int totalResults = 0;
int rows = 0;
while (answer.hasMoreElements()) {// 遍历结果集
SearchResult sr = (SearchResult) answer.next();// 得到符合搜索条件的DN
++rows;
String dn = sr.getName();
log.info(dn);
Attributes Attrs = sr.getAttributes();// 得到符合条件的属性集
if (Attrs != null) {
try {
for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore();) {
Attribute Attr = (Attribute) ne.next();// 得到下一个属性
// 读取属性值
for (NamingEnumeration e = Attr.getAll(); e.hasMore(); totalResults++) {
company = e.next().toString();
JSONObject tempJson = new JSONObject();
tempJson.put(Attr.getID(), company.toString());
resultList.add(tempJson);
}
}
} catch (NamingException e) {
log.info("Throw Exception : " + e.getMessage());
}
}
}
log.info("总共用户数:" + rows);
} catch (NamingException e) {
log.info("Throw Exception : " + e.getMessage());
}finally {
try{
ldapContext.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
return resultList;
}
3.4 重置用户密码

// 管理员重置用户密码,后强制用户首次登录修改密码
public Map<String, String> updateAdPwd(JSONObject json) {
String dn = json.getString("dn");//要修改的帐号(这个dn是查询的用户信息里的dn的值,而不是域账号)
String password = json.getString("password");//新密码
JSONObject admin = new JSONObject();
admin.put("username","aaaaaaa");
admin.put("password", "bbbbbbb");
Map<String,String> map = new HashMap<String,String>();
LdapContext ldapContext = adLoginSSL(admin); //连接636端口域
ModificationItem[] mods = new ModificationItem[2];
if (ldapContext!=null){
try {
String newQuotedPassword = "\"" + password + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
// unicodePwd:修改的字段,newUnicodePassword:修改的值
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("unicodePwd", newUnicodePassword));
mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("pwdLastSet", "0")); // 首次登录必须修改密码

// 修改密码
ldapContext.modifyAttributes(dn, mods);
map.put("result", "S");
map.put("message","成功");
}catch (Exception e){
map.put("result","E");
map.put("message", "无法重置密码");
}finally {
try{
ldapContext.close();
}catch (Exception e){
e.printStackTrace();
}
}
}else {
log.info("");
map.put("result","E");
map.put("message", "验证失败");
}
return map;
}
3.5 域账号解锁

// 表示锁定的字段需要测试,不一定这个lockoutTime
public Map<String, String> deblocking(JSONObject json) {
JSONObject admin = new JSONObject();
String dn = json.getString("dn"); //被解锁的帐号(这个dn指的是查询用户信息里的dn的值,不是域账号)
admin.put("username","aaaaaa");
admin.put("password","bbbbbb");
Map<String,String> map = new HashMap<String,String>();
LdapContext ldapContext = adLogin(admin);
ModificationItem[] mods = new ModificationItem[1];
if (ldapContext!=null){
try {
      // "0" 表示未锁定,不为0表示锁定
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("lockoutTime","0"));
// 解锁域帐号
ldapContext.modifyAttributes(dn, mods);
map.put("result", "S");
map.put("message","成功");
}catch (Exception e){
map.put("result","E");
map.put("message", "解锁失败");
}finally {
try{
ldapContext.close();
}catch (Exception e){
e.printStackTrace();
}
}
}else {
map.put("result","E");
map.put("message", "验证失败");
}
return map;

如转截您的文章:本博主只是为传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请及时与我们联系,我们将及时更正、删除处理。

本文链接:http://blog.xiayi365.com/post/218.html

标签: LDAP使用
分享给朋友:

相关文章

高手教你解决电脑关不了机的现象

高手教你解决电脑关不了机的现象

我们经常会碰到电脑关机不了的现象,这可怎么办呢?别急,下面小编教大家解决电脑无法关机的状况。 为什么电脑关不了机? 1.大多数情况是病毒木马造成电脑不能正常关机的,比较典型的病毒是绑架类木马, 它...

用coreldraw怎样做条形码

用coreldraw怎样做条形码

不知道你用的是哪个版本,我用的是coreldraw12,在“编辑”菜单下点击“插入条形码”,然后选择你想要的条形码样板,接着输入条形码编号,点击“下一步、下一步、确定”就OK了!...

pci.sys文件损坏 pci.sys文件丢失解决

pci.sys文件损坏 pci.sys文件丢失解决

今天在单位碰到了这个问题: 开机后在要进入XP系统的时候提示c:\windows\system32\drivers\pci.sys 丢失 从提示中看,似乎是pci.sys文件丢失造成的。...

去除

去除"此计算机很快就不会再收到google chrome更新

chrome桌面快捷方式—右键—属性—目标—尾部添加 --disable-infobars—应用—确定 即可。 注意“--”前要有个空格...

解决win7系统图片查看器无法正常查看GIF动态图片

解决win7系统图片查看器无法正常查看GIF动态图片

不管是什么系统都有自带一个图片查看器,win7系统也不例外。在win7系统使用过程中遇到了查看GIF动态图片发现动不了,出现这种问题甚是让人纳闷,同一张GIF动态图片在以前的XP中还是可以闪动的,怎么...

恢复丢失数据的方法

恢复丢失数据的方法

1;误将一个系统文件删除了,导致计算机运行的不正常的恢复方法如果文件被删到回收站,可以通过回收站的还原功能来恢复:打开"回收站",并选中被删的文件;然后单击"回收站任务&...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。