向 Windows Active Directory 新增網域使用者 lwf2_count,並設定密碼、顯示名稱、UPN、sAMAccountName,且啟用帳號(預設建立為停用)。
public class TestOper {
public static void main(String[] args) throws BaseException, NamingException, UnsupportedEncodingException {
// 1. 連線配置
Env env = new Env();
env.factory = "com.sun.jndi.ldap.LdapCtxFactory";
env.url = "ldap://10.110.179.175:389";
env.adminUID = "cn=administrator,cn=users,DC=securitytest,DC=boco";
env.adminPWD = "Ba88736612";
DirContext dirContext = LdapConnectionFactory.getDirContext(env);
if (dirContext == null) {
System.err.println("Failed to connect LDAP");
return;
}
try {
// 2. 準備使用者屬性
Map attMap = new HashMap<>();
List objectClass = Arrays.asList("top", "person", "organizationalPerson", "user");
attMap.put("objectClass", objectClass); // 必須:物件類別鏈
attMap.put("cn", "lwf2_count"); // 相對辨識名
attMap.put("sn", "liao"); // 姓
attMap.put("givenName", "wufeng"); // 名
attMap.put("displayName", "liaowufeng"); // 顯示名稱
attMap.put("userPrincipalName", "lwf2_name@securitytest.boco"); // UPN 登入名
attMap.put("sAMAccountName", "lwf2_name"); // 下層相容登入名
// 3. 密碼與帳號控制位元
String newPassword = "bA123456";
attMap.put("unicodePwd", encodePassword(newPassword)); // AD 專用:UTF-16LE 編碼加雙引號
int UF_NORMAL_ACCOUNT = 0x0200;
int UF_DONT_EXPIRE_PASSWD = 0x10000; // 密碼永不過期
// 啟用帳號:NORMAL_ACCOUNT | DONT_EXPIRE_PASSWD
attMap.put("userAccountControl", Integer.toString(UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD));
// 4. 執行建立
String userDN = "CN=lwf2_count,CN=Users,DC=securitytest,DC=boco";
LdapOperUtils.addContext(dirContext, userDN, attMap);
System.out.println("User created and enabled successfully!");
} finally {
LdapConnectionFactory.closeDirContext(dirContext);
}
}
/** AD unicodePwd 格式:UTF-16LE 編碼的 "password" 字串(含雙引號) */
private static byte[] encodePassword(String pwd) throws UnsupportedEncodingException {
String quoted = "\"" + pwd + "\"";
return quoted.getBytes("UTF-16LE");
}
}
AD 使用者必須包含 top → person → organizationalPerson → user 完整鏈,缺一不可。
userPassword:標準 LDAP 屬性,多為明文或雜湊,AD 不支援直接寫入。unicodePwd:AD 專屬,必須為 UTF-16LE 編碼的帶雙引號字串(如 "bA123456"),且僅限 SSL 連線寫入(安全需求)。測試代碼為簡化示範使用明文連線,生產環境務必啟用 SSL。| 常數 | 十六進位 | 含義 |
|---|---|---|
| UF_ACCOUNTDISABLE | 0x0002 | 帳號停用 |
| UF_PASSWD_NOTREQD | 0x0020 | 無需密碼 |
| UF_PASSWD_CANT_CHANGE | 0x0040 | 使用者不可變更密碼 |
| UF_NORMAL_ACCOUNT | 0x0200 | 一般使用者帳號(啟用基礎旗標) |
| UF_DONT_EXPIRE_PASSWD | 0x10000 | 密碼永不過期 |
| UF_PASSWORD_EXPIRED | 0x800000 | 密碼已過期 |
啟用帳號最小組合:UF_NORMAL_ACCOUNT (0x0200)。本範例加上 UF_DONT_EXPIRE_PASSWD 避免密碼過期強制變更。
CN=lwf2_count,CN=Users,DC=securitytest,DC=boco 中:
CN:Common Name(相對辨識名)CN=Users:預設使用者容器(非 OU)DC:網域元件五篇文章完整實作了:
Env:連線參數封裝LdapConnectionFactory:連線池/直連管理、SSL、關閉重試LdapOperUtils:Context 增刪改名、屬性增刪改查、搜尋(單層/子樹/屬性投影)、群組成員維護、認證整合可擴充方向:
PagedResultsControl)支援大量資料DirContext.addNamingListener)歡迎同好交流改進,共建更好用的 LDAP Java 工具箱。