• Java获取AD域内所有用户


    基础知识介绍

    请参考其他资料:AD域介绍与配置 - 云淡风轻~江哥 - 博客园

    废话不多说---上代码

    使用maven生成工程

    mvn archetype:generate -DinteractiveMode=false -DgroupId=com.dilusense.ad -DartifactId=AD -Dversion=1.0.0-SNAPSHOT

    pom文件

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    3. <modelVersion>4.0.0modelVersion>
    4. <groupId>com.dilusense.adgroupId>
    5. <artifactId>ADartifactId>
    6. <packaging>jarpackaging>
    7. <version>1.0.0-SNAPSHOTversion>
    8. <name>ADname>
    9. <url>http://maven.apache.orgurl>
    10. <dependencies>
    11. <dependency>
    12. <groupId>junitgroupId>
    13. <artifactId>junitartifactId>
    14. <version>3.8.1version>
    15. <scope>testscope>
    16. dependency>
    17. <dependency>
    18. <groupId>org.springframeworkgroupId>
    19. <artifactId>spring-beansartifactId>
    20. <version>4.2.6.RELEASEversion>
    21. dependency>
    22. <dependency>
    23. <groupId>org.springframeworkgroupId>
    24. <artifactId>spring-contextartifactId>
    25. <version>4.2.6.RELEASEversion>
    26. dependency>
    27. <dependency>
    28. <groupId>org.springframework.bootgroupId>
    29. <artifactId>spring-boot-starter-mailartifactId>
    30. <version>2.6.4version>
    31. dependency>
    32. <dependency>
    33. <groupId>org.projectlombokgroupId>
    34. <artifactId>lombokartifactId>
    35. <version>RELEASEversion>
    36. <scope>compilescope>
    37. dependency>
    38. <dependency>
    39. <groupId>org.projectlombokgroupId>
    40. <artifactId>lombokartifactId>
    41. <version>RELEASEversion>
    42. <scope>compilescope>
    43. dependency>
    44. dependencies>
    45. project>

    App.java 文件

    1. package com.dilusense.ad;
    2. import org.springframework.stereotype.Component;
    3. import javax.naming.Context;
    4. import javax.naming.NamingEnumeration;
    5. import javax.naming.directory.Attribute;
    6. import javax.naming.directory.Attributes;
    7. import javax.naming.directory.SearchControls;
    8. import javax.naming.directory.SearchResult;
    9. import javax.naming.ldap.InitialLdapContext;
    10. import javax.naming.ldap.LdapContext;
    11. import java.util.ArrayList;
    12. import java.util.Date;
    13. import java.util.Hashtable;
    14. import java.util.List;
    15. //package com.cy.sendmail.util;
    16. /**
    17. * @author fd
    18. * @title: getInfoFromAD
    19. * @projectName DemoForADDomain
    20. * @description: 通过LDAP从AD域获取信息
    21. * @date 2022/8/31 13:36
    22. */
    23. @Component
    24. class GetInfoFromAD {
    25. public void setCtx(LdapContext ctx) {
    26. this.ctx = ctx;
    27. }
    28. //@Value("${ADServer.ip}")
    29. private String ip;
    30. //@Value("${ADServer.port}")
    31. private String port;
    32. //@Value("${ADServer.adminName}")
    33. private String adminName;
    34. //@Value("${ADServer.pwd}")
    35. private String pwd;
    36. //@Value("${ADServer.searchBase}")
    37. private String searchBase;
    38. private LdapContext ctx = null;
    39. public void setIp(String ip) {
    40. this.ip = ip;
    41. }
    42. public void setPort(String port) {
    43. this.port = port;
    44. }
    45. public void setAdminName(String adminName) {
    46. this.adminName = adminName;
    47. }
    48. public void setPwd(String pwd) {
    49. this.pwd = pwd;
    50. }
    51. public void setSearchBase(String searchBase) {
    52. this.searchBase = searchBase;
    53. }
    54. public static void main(String[] args) throws Exception {
    55. try {
    56. GetInfoFromAD obj = new GetInfoFromAD();
    57. obj.setIp("10.0.1.183");
    58. obj.setPort("389");
    59. obj.setAdminName("dilusense\\administrator");
    60. obj.setPwd("Dl1u$ense");
    61. //obj.setSearchBase("OU=X,CN=administrator,=DC=administrator");//DC=aadsync.dilusense.com
    62. obj.setSearchBase("OU=X,DC=dilusense,DC=com");
    63. obj.ldap_connect();
    64. obj.getUserInfo();
    65. } catch (Exception e) {
    66. e.printStackTrace();
    67. }
    68. }
    69. /**
    70. * 用户认证
    71. */
    72. public void ldap_connect() {
    73. String url = "ldap://" + ip + ":" + port;
    74. System.out.println("url" + url);
    75. Hashtable hashEnv = new Hashtable();
    76. // LDAP安全访问级别,"none", "simple", "strong"
    77. hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
    78. // 管理员账号密码
    79. hashEnv.put(Context.SECURITY_PRINCIPAL, adminName);
    80. hashEnv.put(Context.SECURITY_CREDENTIALS, pwd);
    81. // LDAP工厂类
    82. hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    83. hashEnv.put(Context.PROVIDER_URL, url);
    84. try {
    85. ctx = new InitialLdapContext(hashEnv, null);
    86. System.out.println("域控认证成功");
    87. } catch (Exception e) {
    88. System.out.println("域控认证失败");
    89. e.printStackTrace();
    90. }
    91. }
    92. /**
    93. * 关闭连接
    94. */
    95. public void ldap_close(){
    96. try{
    97. if(ctx != null) {
    98. ctx.close();
    99. }
    100. }catch(Exception e){
    101. e.printStackTrace();
    102. }
    103. }
    104. /**
    105. * 获取域控用户信息
    106. */
    107. public List getUserInfo() {
    108. int i = 0;
    109. // 用户信息稽核
    110. List userList = new ArrayList<>();
    111. // 域节点,CN-用户,OU-组,DC-域
    112. String searchBase = this.searchBase;
    113. // LDAP搜索过滤器类
    114. String searchFilter = "objectClass=User";
    115. // 搜索控制器
    116. SearchControls searchCtls = new SearchControls();
    117. // 创建搜索控制器
    118. searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    119. // 设置返回的用户属性,可以不设置,用户返回属性会很多
    120. String returnedAtts[] = {"memberOf", "name", "mail", "userPrincipalName", "pwdlastset", "lockoutTime", "useraccountcontrol"};
    121. // 设置返回属性集
    122. searchCtls.setReturningAttributes(returnedAtts);
    123. try{
    124. System.out.println("ctx.search");
    125. // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
    126. NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
    127. System.out.println("ctx.search2");
    128. // 遍历结果
    129. while (answer.hasMore()) {
    130. ADUser user = new ADUser(); // 定义用户
    131. SearchResult sr = (SearchResult) answer.next();// 根据查询属性返回查询结果
    132. Attributes attrs = sr.getAttributes();// 得到符合条件的属性集
    133. // 获取对象属性
    134. Attribute name = attrs.get("name"); // 用户中文名
    135. System.out.println(++i + "用户中文名:");
    136. System.out.println(name);
    137. user.setDisplayName(name.get().toString());
    138. Attribute mail = attrs.get("mail"); // 用户邮箱
    139. System.out.println(mail);
    140. user.setMail(mail == null ? "" : mail.get().toString());
    141. Attribute pwdLastSet = attrs.get("pwdlastset"); // 上次密码修改时间
    142. user.setPwdLastSet(adExpiresToDate(Long.valueOf(pwdLastSet.get().toString()))); // 进行字符戳转换后赋值
    143. Attribute uac = attrs.get("useraccountcontrol");// 用户控制,用于判断用户密码是否永不过期,该属性详情参考上面链接
    144. user.setUserAccountControl(uac.get().toString());
    145. if(!user.getMail().equals("")) { // 有邮箱,且密码设置了非永久不过期的账号
    146. userList.add(user);
    147. System.out.println(++i + "----" +user.toString());
    148. }
    149. }
    150. }catch(Exception e){
    151. e.printStackTrace();
    152. }
    153. return userList;
    154. }
    155. /**
    156. * AD账户时间戳转换,windows NT时间转Date
    157. * @param pwdLastSet
    158. * @return
    159. */
    160. public Date adExpiresToDate(long pwdLastSet){
    161. long timeStamp = pwdLastSet - 116445312000000000L;
    162. timeStamp = Long.parseLong(String.valueOf(timeStamp).substring(0, 13)) + 57599875L;
    163. return new Date(timeStamp);
    164. }
    165. }
    166. class ADUser {
    167. private String displayName;
    168. private String mail;
    169. private String userAccountControl;
    170. private Date pwdLastSet;
    171. public String getDisplayName() {
    172. return displayName;
    173. }
    174. public void setDisplayName(String displayName) {
    175. this.displayName = displayName;
    176. }
    177. public String getMail() {
    178. return mail;
    179. }
    180. public void setMail(String mail) {
    181. this.mail = mail;
    182. }
    183. public String getUserAccountControl() {
    184. return userAccountControl;
    185. }
    186. public void setUserAccountControl(String userAccountControl) {
    187. this.userAccountControl = userAccountControl;
    188. }
    189. public Date getPwdLastSet() {
    190. return pwdLastSet;
    191. }
    192. public void setPwdLastSet(Date pwdLastSet) {
    193. this.pwdLastSet = pwdLastSet;
    194. }
    195. }

    代码中 SearchBase 如何设置

    打开AD域服务界面

    打开步骤 打开 Active Directory 用户和计算机 单击“开始”,再单击“运行”。 在“打开”框中,键入 dsa.msc,再单击“确定”。 —或者— 单击“开始”,指向“所有程序”,再指向“Microsoft Exchange”,然后单击“Active Directory 用户和计算机”。如下界面:

    DC:域控制器, 就是一台服务器,负责每一台联入网络的电脑和用户的验证工作。
    OU:组织单元

    所以, SearchBase="OU=X,DC=dilusense,DC=com",两个DC,不能合并,顺序也不能变。

    另:windows出于安全的考虑,域用户的密码只能修改,不能获取。

  • 相关阅读:
    Java学习之方法重写/覆盖
    函数栈帧的形成与释放
    Oracle 存储过程数据插入临时表慢以及SQL语句查询慢
    【HarmonyOS】【JAVA UI】HarmonyOS 如何集成KLog
    不同类型的RFID标签及其应用场景浅析
    精确率、准确率、召回率
    三驾马车、四大赛道,元宇宙如何领跑数字经济?
    Centos Linux 7系统基础配置
    【计算机视觉】上采样和下采样
    总结40条常用Linux命令的基本使用
  • 原文地址:https://blog.csdn.net/huangjiazhi_/article/details/126620752