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如下所示:

总之:Active Directory =LDAP服务器+LDAP应用(Windows域控)。ActiveDirectory先实现一个LDAP服务器,然后自己先用这个LDAP服务器实现了自己的一个具体应用(域控)。

3.使用LDAP操作AD域

(1). 特别注意:Java操作查询域用户信息获取到的数据和域管理员在电脑上操作查询的数据可能会存在差异(同一个意思的表示字段,两者可能不同)。

(3). 端口389用于一般的连接,例如登录,查询等非密码操作,端口636安全性较高,用户密码相关操作,例如修改密码等。

(4). 域控可能有多台服务器,之间数据同步不及时,可能会导致已经修改的数据被覆盖掉,这个要么域控缩短同步的时间差,要么同时修改每一台服务器的数据。

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 env = new Hashtable();

//用户名称,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;

}

}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;

}查询域用户信息

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 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;

}重置用户密码

// 管理员重置用户密码,后强制用户首次登录修改密码

public Map 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 map = new HashMap();

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;

}域账号解锁

// 表示锁定的字段需要测试,不一定这个lockoutTime

public Map deblocking(JSONObject json) {

JSONObject admin = new JSONObject();

String dn = json.getString("dn"); //被解锁的帐号(这个dn指的是查询用户信息里的dn的值,不是域账号)

admin.put("username","aaaaaa");

admin.put("password","bbbbbb");

Map map = new HashMap();

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;

}

参考文献:

ad域控查看ldap端口命令_工作笔记(一)LDAP和AD介绍以及使用LDAP操作AD域相关推荐

  1. CentOS7查看开放端口命令

    CentOS7查看开放端口命令 CentOS7的开放关闭查看端口都是用防火墙来控制的,具体命令如下: 查看已经开放的端口: Linux代码   firewall-cmd --list-ports 开启 ...

  2. 查看Centos端口命令

    查看Centos端口命令: # netstat -lntp #查看监听(Listen)的端口 # netstat -antp #查看所有建立的TCP连接 其他关于查看服务器网络信息命令: 1.查看Li ...

  3. CentOS7查看开放端口命令、查看端口占用情况和开启端口命令、杀掉进程

    文章目录 一.CentOS7查看开放端口命令 查看已经开放的端口 开启端口 命令含义 重启防火墙 停止firewall 禁止firewall开机启动 二.Centos查看端口占用情况和开启端口命令 列 ...

  4. 域控查看ldap端口命令_LDAP基础安装与简单入门使用

    0x00 前言简述 主要产品 基本模型 应用场景 0x01 环境安装 基于 yum 安装 基于 Docker 安装 0x02 LDAP配置&命令 slapd 命令 ldapsearch 命令 ...

  5. 查看电脑配置命令_注册表

    查看电脑配置命令 2008年06月16日 星期一 13:59 打开注册表 开始--运行--regedit 什么是注册表? 注册表因为它复杂的结构和没有任何联系的CLSID键使得它可能看上去很神秘.不幸 ...

  6. 查看ssh端口号_萌新云服务器折腾记-SSH配置

    很早以前就想买个服务器自己玩一下(虽然我啥也不会),但是阿里云昂贵的价格让我望而却步,这次双十一发现了一个大好机会,以超低价格买了一台1核2G的ECS(三年,超开心).买完以后进控制台一看,一脸懵,这 ...

  7. curl查看swift状态命令_前端应该会的23个linux常用命令

    (给前端大学加星标,提升前端技能.) 作者:null仔 https://segmentfault.com/a/1190000021439560 1.ls 命令 : 显示目录内容列表 Linux ls ...

  8. debian查看ip地址命令_鲜为人知而又实用的 Linux 命令大全

     点击"Cisco思科CCIE俱乐部"→点击右上角"..."→"设为星标"   资讯丨干货丨入群 联系小E微信:SPOTO123456 Li ...

  9. centos7查看udp端口_CentOS7查看开放端口命令及开放端口号

    CentOS 7查看以开放端口命令: firewall-cmd -list-ports 查看端口是否开放命令: 第一个方法就是使用lsof -i:端口号命令行,例如lsof -i:80.如果没有任何信 ...

最新文章

  1. 浏览器对象模型:window对象2
  2. Imageloader5-ImageLoader的变量初始化
  3. 杭电find the night
  4. c语言单片机4*4键盘程序,求51单片机矩阵4*4键盘程序,P0口接一个数码管,P3口接矩阵键盘,C语言的...
  5. 从PHP5到PHP7自我封装MongoDB以及平滑升级
  6. 牛客多校4 - Count New String(序列自动机+广义后缀自动机)
  7. oracle rowID切片,Oracle中的rowid
  8. 举例说明语言接触会造成哪些结果_语言学概论全真模拟演练(二)
  9. 【转贴】龙芯内核发展策略 已经支持k8s
  10. 阿里云、腾讯云和华为云618活动细节对比
  11. EverWeb for Mac(网页设计软件)
  12. ThinkPHP5.0版本和ThinkPHP3.2版本的差别
  13. http实时推送技术
  14. 防勒索病毒奇兵——MCK(云私钥)
  15. mui mysql_mui框架使用心得
  16. 贝壳找房原生爬虫租房分析
  17. 群晖服务器文件管理套件,群晖drive套件的使用教程
  18. 利用开源工具搭一套汉英翻译系统(二):词对齐
  19. Python - 如何用turtle库画一个微笑表情包
  20. 单片机——IIC协议与24C02

热门文章

  1. springcloud微服务项目解析与服务拆分
  2. POJ 2579 HDU 1218 Blurred Vision(水~)
  3. Azure: Azure AD(For Development)的使用
  4. java编写火车订票系统_毕业设计(论文)-基于JavaWeb技术的火车订票系统.doc
  5. 脑机接口专栏 | 利用黎曼几何分析EEG脑电信号(一)
  6. 【比赛总结】2022十四届华中杯数学建模比赛总结
  7. Leopard中修改分辨率
  8. Word 2016 撰写论文(1): 公式居中、编号右对齐
  9. Freckles - 九度 OJ 1144
  10. 发生线下地推风波,水滴筹冤吗?