| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- package com.uas.eis.serviceImpl;
- import com.uas.eis.core.LdapConnectionManager;
- import com.uas.eis.core.config.ADConfig;
- import com.uas.eis.dao.BaseDao;
- import com.uas.eis.entity.ADUser;
- import com.uas.eis.entity.Employee;
- import com.uas.eis.entity.HrOrg;
- import com.uas.eis.utils.PinyinUtils;
- import com.uas.eis.utils.StringUtil;
- import org.apache.directory.api.ldap.model.cursor.CursorException;
- import org.apache.directory.api.ldap.model.cursor.EntryCursor;
- import org.apache.directory.api.ldap.model.entry.*;
- import org.apache.directory.api.ldap.model.exception.LdapException;
- import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
- import org.apache.directory.api.ldap.model.message.ModifyDnRequest;
- import org.apache.directory.api.ldap.model.message.SearchScope;
- import org.apache.directory.api.ldap.model.name.Rdn;
- import org.apache.directory.ldap.client.api.LdapConnection;
- import org.apache.directory.api.ldap.model.name.Dn;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Lazy;
- import org.springframework.stereotype.Service;
- import java.io.IOException;
- import java.io.UnsupportedEncodingException;
- import java.util.*;
- @Service
- public class ADSyncService {
- private final Logger logger = LoggerFactory.getLogger(getClass());
- @Autowired
- @Lazy
- private LdapConnectionManager ldapConnectionManager;
- @Autowired
- private ADConfig adConfig;
- @Autowired
- private BaseDao baseDao;
- @Autowired
- private UasSyncService uasSyncService;
- public void syncUser() {
- LdapConnection connection = ldapConnectionManager.getConnection();
- List<Employee> employeeList = uasSyncService.getADUserList();
- //List<ADUser> adUserList = getUsers(connection);
- List<HrOrg> orgList = uasSyncService.getADOrgList();
- for (Employee employee : employeeList) {
- if(employee.getEm_adid()!=null){
- //判断是否需要更新组织
- if("离职".equals(employee.getEm_class())){
- disableUser(employee.getEm_adid(),connection);
- //baseDao.updateByCondition("employee","em_adid=null","em_code='"+employee.getEm_code()+"'");
- }else {
- Optional<HrOrg> orgOptional = orgList.stream().filter(org -> org.getOr_code().equals(employee.getOrcode())).findFirst();
- logger.info("同步用户更新:{}",employee.getEm_name());
- updateUserDescription(employee.getEm_adid(),employee.getEmjob());
- if(orgOptional.isPresent()){
- String newOUPath = getOUPath(orgOptional.get().getOr_path());
- logger.info("同步用户更新:oldpath{},newpath{}",getUserOUPath(employee.getEm_adid()),newOUPath);
- if(!getUserOUPath(employee.getEm_adid()).equals(newOUPath)){
- moveUser(employee.getEm_adid(),"CN="+employee.getEm_name()+","+newOUPath,connection);
- baseDao.updateByCondition("employee","em_adid='CN="+employee.getEm_name()+","+newOUPath+"'","em_code='"+employee.getEm_code()+"'");
- }
- }
- }
- }else if (!"其它人员".equals(employee.getEm_emptype()) && !"离职".equals(employee.getEm_class())) {
- Optional<HrOrg> orgOptional = orgList.stream().filter(org -> org.getOr_code().equals(employee.getOrcode())).findFirst();
- if(orgOptional.isPresent()){
- String ouPath = getOUPath(orgOptional.get().getOr_path());
- String adid = addUser(employee.getEm_code(),PinyinUtils.getCustomPinyin(employee.getEm_name()),employee.getEm_name(),ouPath,employee.getEm_password(), employee.getEmjob());
- if(adid!=null){
- baseDao.updateByCondition("employee","em_adid='"+adid+"'","em_code='"+employee.getEm_code()+"'");
- }
- }
- }
- }
- }
- public String addUser(String userCode,String userName,String displayName, String ouName, String password,String job) {
- LdapConnection connection = ldapConnectionManager.getConnection();
- Dn dn = null;
- logger.info("添加用户:{},displayName:{},ouName:{},password{}",userName,displayName,ouName,password);
- try {
- dn = new Dn("CN="+displayName+"," + ouName);
- Entry entry = new DefaultEntry(
- dn,
- "objectClass: top",
- "objectClass: person",
- "objectClass: organizationalPerson",
- "objectClass: user",
- "sAMAccountName: " + userName,
- "userPrincipalName: " + userName + "@" + adConfig.getBaseDn().replace("DC=", "").replace(",", "."),
- "userPassword: " + password
- );
- //处理中文写入异常问题
- entry.add("cn",displayName);
- entry.add("displayName",displayName);
- entry.add("givenName", displayName.substring(0, 1));
- entry.add("sn", displayName.substring(1));
- entry.add("description", job);
- entry.add("userAccountControl", "544");
- connection.add(entry);
- return "CN="+displayName+"," + ouName;
- } catch (Exception e) {
- if(e.getMessage().contains("(ENTRY_EXISTS)")){
- return "CN="+displayName+"," + ouName;
- }else if(e.getMessage().contains("problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 90290 (userPrincipalName)")) {
- return addUser(userCode,userName+""+userCode,displayName,ouName,password,job);
- }
- logger.error("添加用户失败:{},错误{}",userName,e.getMessage());
- return null;
- }
- }
- //更新用户信息
- public void updateUserDescription(String userName, String newDescription) {
- LdapConnection connection = null;
- try {
- connection = ldapConnectionManager.getConnection();
- Dn dn = new Dn( userName);
- Entry entry = new DefaultEntry(
- dn,
- "objectClass: top",
- "objectClass: organizationalPerson"
- );
- connection.modify(dn, new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, "description", newDescription));
- } catch (Exception e) {
- logger.info("updateOrgDescription 更新组织描述失败:{}",e.getMessage());
- }finally {
- if (connection != null) {
- try {
- connection.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
- public void disableUser(String userDn, LdapConnection connection) {
- if(connection==null || !connection.isConnected()){
- connection = ldapConnectionManager.getConnection();
- }
- try {
- Dn dn = new Dn( userDn);
- Entry entry = new DefaultEntry(
- dn,
- "objectClass: top",
- "objectClass: organizationalPerson"
- );
- connection.modify(dn, new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, "userAccountControl", "2"));
- } catch (Exception e) {
- logger.info("disableUser 禁用账号失败:{}",e.getMessage());
- }finally {
- if (connection != null) {
- try {
- connection.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
- public void deleteUser(String userDn, LdapConnection connection) {
- if(connection==null || !connection.isConnected()){
- connection = ldapConnectionManager.getConnection();
- }
- try {
- logger.info("删除用户:{}",userDn);
- Dn dn = new Dn(userDn);
- connection.delete(dn);
- logger.info("删除用户成功:{}",userDn);
- } catch (LdapException e) {
- logger.error("删除用户失败:{}",userDn);
- }
- }
- public void moveUser(String oldUserDnStr, String newRdnStr, LdapConnection connection) {
- logger.info("用户 {} 移动组织 {}", oldUserDnStr, newRdnStr);
- if (connection == null || !connection.isConnected()) {
- connection = ldapConnectionManager.getConnection();
- }
- try {
- connection.moveAndRename(oldUserDnStr, newRdnStr,true);
- logger.info("用户 {} 已成功移动到组织 {}", oldUserDnStr, newRdnStr);
- } catch (Exception e) {
- logger.error("移动用户失败: {}", oldUserDnStr, e);
- throw new RuntimeException("移动用户失败: " + e.getMessage());
- }
- }
- //初始化用户
- public void initUser() throws IOException {
- LdapConnection connection = ldapConnectionManager.getConnection();
- List<Employee> employeeList = uasSyncService.getADUserList();
- List<ADUser> adUserList = getUsers(connection);
- List<HrOrg> orgList = uasSyncService.getADOrgList();
- /* for (ADUser adUser : adUserList) {
- System.out.println(adUser.getUserCn());
- for (Employee employee : employeeList) {
- if(employee.getEm_name().equals(adUser.getUserCn()) && !StringUtil.hasText(employee.getEm_adid()) ){
- baseDao.updateByCondition("employee","em_adid='"+adUser.getUserDn()+"'", "em_code ='"+employee.getEm_code()+"'");
- break;
- }
- }
- }*/
- for(Employee employee:employeeList){
- if(!StringUtil.hasText(employee.getEm_adid())){
- Optional<ADUser> adUserOptional = adUserList.stream().filter(adUser -> adUser.getUserDn().equals(employee.getEm_adid())).findFirst();
- if(!adUserOptional.isPresent()){
- //System.out.println("用户不存在:"+employee.getEm_adid()+"-"+employee.getEm_name());
- //baseDao.updateByCondition("employee","em_adid=null", "em_code ='"+employee.getEm_code()+"'");
- if(!"其它人员".equals(employee.getEm_emptype()) && !"离职".equals(employee.getEm_class())) {
- Optional<HrOrg> orgOptional = orgList.stream().filter(org -> org.getOr_code().equals(employee.getOrcode())).findFirst();
- if(orgOptional.isPresent()){
- String ouPath = getOUPath(orgOptional.get().getOr_path());
- String adid = addUser(employee.getEm_code(),PinyinUtils.getCustomPinyin(employee.getEm_name()),employee.getEm_name(),ouPath,employee.getEm_password(), employee.getEmjob());
- if(adid!=null){
- baseDao.updateByCondition("employee","em_adid='"+adid+"'","em_code='"+employee.getEm_code()+"'");
- }
- }
- }
- }
- }
- }
- //移动人员组织
- }
- public List<ADUser> getUsers(LdapConnection connection) throws IOException {
- List<ADUser> userList = new ArrayList<>();
- if(connection==null || !connection.isConnected()){
- connection = ldapConnectionManager.getConnection();
- }
- try {
- // 搜索所有用户
- String filter = "(objectClass=organizationalPerson)";
- EntryCursor result = connection.search(
- "OU=User,"+adConfig.getBaseDn(), // AD基础DN,从配置文件获取
- filter,
- SearchScope.SUBTREE
- );
- Entry entry;
- while (result.next()) {
- try {
- entry =result.get();
- ADUser adUser = new ADUser();
- adUser.setUserDn(entry.getDn().toString());
- adUser.setUserCn(entry.get("cn").get().getString());
- adUser.setAccountName(entry.get("sAMAccountName").get().getString());
- adUser.setUserPrincipalName(entry.get("userPrincipalName").get().getString());
- userList.add(adUser);
- } catch (CursorException e) {
- e.printStackTrace();
- }
- }
- return userList;
- } catch (LdapException e) {
- e.printStackTrace();
- } catch (CursorException e) {
- e.printStackTrace();
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- return null;
- }
- public void syncOrg() {
- LdapConnection connection = ldapConnectionManager.getConnection();
- List<HrOrg> orgList = uasSyncService.getADOrgList();
- logger.info("同步组织数量:{}",orgList.size());
- List<String> orgDns = getOrganizations(connection);
- //判断组织是否存在
- for (HrOrg org : orgList) {
- if("已审核".equals(org.getOr_status())) {
- if(!orgDns.isEmpty()){
- boolean isExist = false;
- for(String orgDn : orgDns){
- String orgDescription = orgDn.substring(orgDn.indexOf(";")+1);
- String orgPath = orgDn.split(";")[0];
- // 组织编号匹配成功
- if(StringUtil.hasText(orgDescription) && orgDescription.equals(org.getOr_code())){
- //组织编号一致
- if(! orgPath.startsWith(getOUPath(org.getOr_path()))){
- //组织路径不一致,则更新组织层级信息
- logger.info("updateOrg 更新组织信息:old{},new{},orgCode{}",orgPath,getOUPath(org.getOr_path()) , orgDescription);
- updateOrg(orgPath, getOUPath(org.getOr_path()), connection);
- }
- isExist =true;
- break;
- }
- //组织编号匹配不成功,路径匹配相同
- if(orgPath.equals(getOUPath(org.getOr_path()))){
- if(!StringUtil.hasText(orgDescription)){
- //更新AD域组织编号信息
- updateOrgDescription(orgDn.split(";")[0], org.getOr_code());
- }
- isExist =true;
- break;
- }
- }
- //不存在的组织
- if(!isExist){
- //添加组织
- addOrg(org, connection);
- }
- }
- }
- }
- //判断AD域组织存在但没有已审核的组织信息,删除AD域组织
- for(String orgDn : orgDns){
- String orgDescription = orgDn.substring(orgDn.indexOf(";")+1);
- if(StringUtil.hasText(orgDescription)){
- //未成功匹配的组织资料
- if(!orgList.stream().anyMatch(org -> !"已禁用".equals(org.getOr_status()) && org.getOr_code().equals(orgDescription))){
- //删除AD域组织
- deleteOrg(orgDn.split(";")[0], connection);
- }
- }
- }
- }
- public void addOrg(HrOrg org, LdapConnection connection) {
- if(connection==null || !connection.isConnected()){
- connection=ldapConnectionManager.getConnection();
- }
- try {
- logger.info("添加组织{}",org.getOr_path());
- Dn dn = new Dn(getOUPath(org.getOr_path()));
- Entry entry = new DefaultEntry(
- dn,
- "objectClass: top",
- "objectClass: organizationalUnit"
- );
- entry.add("description", org.getOr_code());
- connection.add(entry);
- logger.info("添加组织{}成功",org.getOr_path());
- } catch (Exception e) {
- logger.error("添加组织失败",e);
- }
- }
- public void deleteOrg(String ouName, LdapConnection connection) {
- if(connection==null || !connection.isConnected()){
- connection=ldapConnectionManager.getConnection();
- }
- Dn dn = null;
- logger.info("删除组织{}",ouName);
- try {
- dn = new Dn( ouName );
- String filter = "(objectClass=organizationalUnit)||(objectClass=user)";
- EntryCursor result = connection.search(
- ouName,
- filter,
- SearchScope.ONELEVEL, // 搜索所有子节点
- "dn"
- );
- if (result.next()) {
- logger.info("组织下存在下级,无法删除{}",ouName);
- }else {
- connection.delete(dn);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- logger.info("删除组织{}成功",ouName);
- }
- public void updateOrg(String oldOUName,String newOuName, LdapConnection connection) {
- if(connection==null || !connection.isConnected()){
- connection=ldapConnectionManager.getConnection();
- }
- logger.info("更新组织{}为{}",oldOUName,newOuName);
- try {
- connection.moveAndRename(oldOUName,newOuName,true);
- } catch (Exception e) {
- logger.error(e.getMessage());
- e.printStackTrace();
- }
- logger.info("更新组织{}为{} 成功",oldOUName,newOuName);
- }
- /**
- * 修改自定义description属性
- * */
- public void updateOrgDescription(String orgName, String newDescription) {
- LdapConnection connection = null;
- try {
- connection = ldapConnectionManager.getConnection();
- Dn dn = new Dn( orgName);
- Entry entry = new DefaultEntry(
- dn,
- "objectClass: top",
- "objectClass: organizationalUnit"
- );
- connection.modify(dn, new DefaultModification(ModificationOperation.REPLACE_ATTRIBUTE, "description", newDescription));
- } catch (Exception e) {
- logger.info("updateOrgDescription 更新组织描述失败:{}",e.getMessage());
- }finally {
- if (connection != null) {
- try {
- connection.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
- /**
- * 通过自定义description查看组织信息
- * */
- public List<String> findOrganizationsByDescription(String description) throws IOException {
- LdapConnection connection = null;
- try {
- connection = ldapConnectionManager.getConnection();
- // 设置LDAP搜索过滤器,匹配organizationalUnit且description包含搜索词
- String filter = String.format("(&(objectClass=organizationalUnit)(description=*%s*))", description);
- EntryCursor result = connection.search(
- adConfig.getBaseDn(), // 从配置的基础DN开始搜索
- filter,
- SearchScope.SUBTREE, // 搜索所有子节点
- "dn" // 只返回DN属性
- );
- List<String> orgDns = new ArrayList<>();
- return orgDns;
- } catch (Exception e) {
- e.printStackTrace();
- }
- finally {
- if (connection != null) {
- connection.close();
- }
- }
- return null;
- }
- private String getOUPath(String orpath){
- String[] paths=orpath.split("-");
- String ouPath="";
- for(int i=paths.length-1;i>=0;i--){
- ouPath+="OU="+paths[i]+",";
- }
- return ouPath.substring(0,ouPath.length()-1)+",OU=User,"+adConfig.getBaseDn();
- }
- private String getUserOUPath(String userPath){
- return userPath.substring(userPath.indexOf(",")+1);
- }
- public List<String> getOrganizations(LdapConnection connection) {
- if(connection==null || !connection.isConnected()){
- connection = ldapConnectionManager.getConnection();
- }
- try {
- // 搜索所有组织单元
- List<String> orgDns = new ArrayList<>();
- String filter = "(objectClass=organizationalUnit)";
- EntryCursor result = connection.search(
- "OU=User,"+adConfig.getBaseDn(), // AD基础DN,从配置文件获取
- filter,
- SearchScope.SUBTREE, // 搜索所有子节点
- new String[] {"dn", "description"}
- );
- Entry entry = null;
- while (result.next()) {
- try {
- entry =result.get();
- //排除掉根目录
- if(!entry.getDn().toString().startsWith("OU=User")){
- orgDns.add(String.format("%s;%s", entry.getDn().toString(),
- StringUtil.hasText(entry.get("description"))?entry.get("description").get():""));
- }
- } catch (CursorException e) {
- e.printStackTrace();
- }
- }
- return orgDns;
- } catch (LdapException e) {
- e.printStackTrace();
- } catch (CursorException e) {
- throw new RuntimeException(e);
- } finally {
- if (connection != null) {
- try {
- connection.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- return null;
- }
- }
|