參考:
package com.cy.sendmail.util;
import com.cy.sendmail.domain.ADUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.*;
/**
* @author z
* @title: getInfoFromAD
* @projectName sendmail
* @description: 通過LDAP從AD域獲取信息
* @date 2020/11/16 13:49
*/
@Component
public class GetInfoFromAD {
@Value("${ADServer.ip}")
private String ip;
@Value("${ADServer.port}")
private String port;
@Value("${ADServer.adminName}")
private String adminName;
@Value("${ADServer.pwd}")
private String pwd;
@Value("${ADServer.searchBase}")
private String searchBase;
private LdapContext ctx = null;
/**
* 用戶認證
*/
public void ldap_connect() {
String url = "ldap://" + ip + ":" + port;
Hashtable hashEnv = new Hashtable();
// LDAP安全訪問級別,"none", "simple", "strong"
hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
// 管理員賬號密碼
hashEnv.put(Context.SECURITY_PRINCIPAL, adminName);
hashEnv.put(Context.SECURITY_CREDENTIALS, pwd);
// LDAP工廠類
hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
hashEnv.put(Context.PROVIDER_URL, url);
try {
ctx = new InitialLdapContext(hashEnv, null);
System.out.println("域控認證成功");
} catch (Exception e) {
System.out.println("域控認證失敗");
e.printStackTrace();
}
}
/**
* 關(guān)閉連接
*/
public void ldap_close(){
try{
if(ctx != null) {
ctx.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 獲取域控用戶信息
*/
public List<ADUser> getUserInfo() {
int i = 0;
// 用戶信息稽核
List<ADUser> userList = new ArrayList<>();
// 域節(jié)點,CN-用戶,OU-組灸撰,DC-域
String searchBase = this.searchBase;
// LDAP搜索過濾器類
String searchFilter = "objectClass=User";
// 搜索控制器
SearchControls searchCtls = new SearchControls();
// 創(chuàng)建搜索控制器
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// 設(shè)置返回的用戶屬性,可以不設(shè)置拼坎,用戶返回屬性會很多
String returnedAtts[] = {"memberOf", "name", "mail", "userPrincipalName", "pwdlastset", "lockoutTime", "useraccountcontrol"};
// 設(shè)置返回屬性集
searchCtls.setReturningAttributes(returnedAtts);
try{
// 根據(jù)設(shè)置的域節(jié)點浮毯、過濾器類和搜索控制器搜索LDAP得到結(jié)果
NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
// 遍歷結(jié)果
while (answer.hasMore()) {
ADUser user = new ADUser(); // 定義用戶
SearchResult sr = (SearchResult) answer.next();// 根據(jù)查詢屬性返回查詢結(jié)果
Attributes attrs = sr.getAttributes();// 得到符合條件的屬性集
// 獲取對象屬性
Attribute name = attrs.get("name"); // 用戶中文名
user.setDisplayName(name.get().toString());
Attribute mail = attrs.get("mail"); // 用戶郵箱
user.setMail(mail == null ? "" : mail.get().toString());
Attribute pwdLastSet = attrs.get("pwdlastset"); // 上次密碼修改時間
user.setPwdLastSet(adExpiresToDate(Long.valueOf(pwdLastSet.get().toString()))); // 進行字符戳轉(zhuǎn)換后賦值
Attribute uac = attrs.get("useraccountcontrol");// 用戶控制,用于判斷用戶密碼是否永不過期泰鸡,該屬性詳情參考上面鏈接
user.setUserAccountControl(uac.get().toString());
if(!user.getMail().equals("")) { // 有郵箱债蓝,且密碼設(shè)置了非永久不過期的賬號
userList.add(user);
System.out.println(++i + "----" +user.toString());
}
}
}catch(Exception e){
e.printStackTrace();
}
return userList;
}
/**
* AD賬戶時間戳轉(zhuǎn)換,windows NT時間轉(zhuǎn)Date
* @param pwdLastSet
* @return
*/
public Date adExpiresToDate(long pwdLastSet){
long timeStamp = pwdLastSet - 116445312000000000L;
timeStamp = Long.parseLong(String.valueOf(timeStamp).substring(0, 13)) + 57599875L;
return new Date(timeStamp);
}
}
①2022..4.11更新盛龄,發(fā)現(xiàn)BUG:
當域控用戶超過1000條記錄時饰迹,系統(tǒng)報錯超過MaxPageLimit,域控服務(wù)器默認只提供1000條讯嫂,需要在AD域控服務(wù)器調(diào)整策略蹦锋,報錯信息:
javax.naming.SizeLimitExceededException: [LDAP: error code 4 - SizeLimit Exceeded]: remaining name '***********************'
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者