public static List
public static List> searchContextSub(DirContext context, String cn,
String filter, String[] returnedAtts) throws NamingException {
List> resultList = new ArrayList<>();
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctls.setReturningAttributes(returnedAtts); // 關鍵:只傳輸需要屬性
NamingEnumeration results = context.search(cn, filter, ctls);
// 迭代邏輯同上,略...
return resultList;
}
public static List> searchContextOne(DirContext context, String cn,
String filter, String[] returnedAtts) throws NamingException {
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
ctls.setReturningAttributes(returnedAtts);
// 其餘同 searchContextSub
}
Active Directory 群組成員儲存於 member 或 uniquemember 多值屬性,需移除特定 DN 時:
public static void deleteInAttributes(DirContext ctx, String userDN,
List attList, String attributeName) throws NamingException {
if (attList == null || attList.isEmpty()) return;
int size = attList.size();
ModificationItem[] mods = new ModificationItem[size];
for (int i = 0; i < size; i++) {
mods[i] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
new BasicAttribute(attributeName, attList.get(i)));
}
ctx.modifyAttributes(userDN, mods);
}
用法:deleteInAttributes(ctx, "cn=GroupA,ou=Groups,dc=ex,dc=com", dnList, "member") 批次移除群組成員。
public static boolean authenticate(ConfigDto configDto, String uid, char[] password)
throws NamingException {
Hashtable env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, configDto.getEnvFactory());
env.put(Context.PROVIDER_URL, configDto.getEnvUrl());
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL,
Constants.LDAP_PEOPLE_ATTRIBUTE_UID + "=" + uid + "," + configDto.getEnvPeopleLoc());
env.put(Context.SECURITY_CREDENTIALS, password);
try {
new InitialDirContext(env);
log.debug("User " + uid + " authenticated successfully");
return true;
} catch (AuthenticationException ex) {
log.error("User " + uid + " authentication failed: invalid credentials");
return false;
}
}
設計精華:直接嘗試以使用者 DN 建立連線,成功即通過驗證,失敗捕獲 AuthenticationException。無需管理員權限,符合最小權限原則,且自動驗證帳號狀態(鎖定、過期、停用皆會導致綁定失敗)。
SUBTREE 遞歸全樹,資料量大時極慢;精確知道目標層級請用 ONELEVEL 或 OBJECT_SCOPE。setReturningAttributes() 限制網路傳輸與解析開銷。deleteInAttributes 批次操作:單次 modifyAttributes 送出陣列,比迴圈單獨呼叫少 N-1 次網路往返。char[] 用畢立即清零(此處省略)。至此核心功能完備,最後一篇將示範完整整合測試案例:建立 AD 使用者、設定屬性、啟用帳號。