5 changed files with 390 additions and 10 deletions
-
98src/main/java/com/spring/common/utils/LdapReadUtils.java
-
83src/main/java/com/spring/config/LdapAccountInitLoad.java
-
143src/main/java/com/spring/modules/sys/service/impl/CheckLdapDirectoryImpl.java
-
75src/main/java/com/spring/modules/sys/task/LdapAccountRefreshTask.java
-
1src/main/resources/application-dev.yml
@ -0,0 +1,98 @@ |
|||
package com.spring.common.utils; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
import javax.naming.NamingEnumeration; |
|||
import javax.naming.NamingException; |
|||
import javax.naming.PartialResultException; |
|||
import javax.naming.directory.Attributes; |
|||
import javax.naming.directory.SearchControls; |
|||
import javax.naming.directory.SearchResult; |
|||
import javax.naming.ldap.Control; |
|||
import javax.naming.ldap.LdapContext; |
|||
import javax.naming.ldap.PagedResultsControl; |
|||
import javax.naming.ldap.PagedResultsResponseControl; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
|
|||
/** |
|||
* |
|||
* @ClassName: LdapReadUtils |
|||
* @Description: 读取数据 |
|||
* @author: LR |
|||
* @date: 2025年9月5日 下午12:04:30 |
|||
* @Copyright: |
|||
*/ |
|||
public class LdapReadUtils { |
|||
private static final Logger logger = LoggerFactory.getLogger(LdapReadUtils.class); |
|||
|
|||
/** |
|||
* |
|||
* @Title: getAllLdapAccount |
|||
* @Description: 查询所有域控行号 通过分页查询来做 |
|||
* @author: LR |
|||
* @date 2025年9月5日 下午12:07:09 |
|||
* @return: Map<String,String> |
|||
*/ |
|||
public static Map<String, String> getAllLdapAccount(LdapContext ctx, String ldapBase) throws NamingException, IOException { |
|||
byte[] cookie = null; |
|||
// 设置返回所有属性 |
|||
SearchControls controls = new SearchControls(); |
|||
controls.setReturningAttributes(new String[] { |
|||
"sAMAccountName", "displayName", "distinguishedName", "manager" |
|||
}); |
|||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // |
|||
|
|||
String nameFilter = "(&(objectClass=user)(objectCategory=person)(!(objectClass=computer)))"; |
|||
Map<String, String> ldapAccountMap = new HashMap<>(); |
|||
//循环执行 |
|||
do{ |
|||
ctx.setRequestControls(new Control[] |
|||
{new PagedResultsControl(100, cookie, true)}); |
|||
NamingEnumeration<SearchResult> results = null; |
|||
try{ |
|||
results = ctx.search(ldapBase, nameFilter, controls); |
|||
//获取数据 读取人员组织架构+域控账号 |
|||
while (results.hasMore()) { |
|||
SearchResult result = results.next(); |
|||
Attributes attrs = result.getAttributes(); |
|||
String distinguishedName = attrs.get("distinguishedName").get().toString(); |
|||
String sAMAccountName = attrs.get("sAMAccountName").get().toString(); |
|||
logger.info("distinguishedName:"+distinguishedName); |
|||
logger.info("sAMAccountName:"+sAMAccountName); |
|||
ldapAccountMap.put(distinguishedName, sAMAccountName); |
|||
} |
|||
}catch(PartialResultException pre){ |
|||
logger.warn("Search results: {}", pre.getMessage()); |
|||
}finally{ |
|||
ctx.setRequestControls(null); |
|||
} |
|||
// 处理服务器返回的分页响应 |
|||
Control[] controlsResp = ctx.getResponseControls(); |
|||
if (controlsResp != null) { |
|||
for (Control control : controlsResp) { |
|||
if (control instanceof PagedResultsResponseControl) { |
|||
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control; |
|||
cookie = prrc.getCookie(); |
|||
} |
|||
} |
|||
} else { |
|||
cookie = null; |
|||
} |
|||
|
|||
}while(cookie != null && cookie.length > 0); |
|||
|
|||
|
|||
//返回结果数据 |
|||
return ldapAccountMap; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
package com.spring.config; |
|||
|
|||
import java.util.Map; |
|||
import java.util.Properties; |
|||
|
|||
import javax.naming.Context; |
|||
import javax.naming.NamingException; |
|||
import javax.naming.ldap.InitialLdapContext; |
|||
import javax.naming.ldap.LdapContext; |
|||
|
|||
import com.spring.common.utils.LdapReadUtils; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.boot.ApplicationArguments; |
|||
import org.springframework.boot.ApplicationRunner; |
|||
import org.springframework.core.annotation.Order; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* |
|||
* @ClassName: LdapAccountInitLoad |
|||
* @Description: 聚水潭权限数据加载 |
|||
* @author: LR |
|||
* @date: 2022年11月25日 下午2:50:56 |
|||
* @Copyright: |
|||
*/ |
|||
@Component |
|||
@Order(value = 12) |
|||
public class LdapAccountInitLoad implements ApplicationRunner{ |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(LdapAccountInitLoad.class); |
|||
|
|||
@Autowired |
|||
private RedisTemplate<String, Object> redisTemplate; |
|||
|
|||
@Value("${spring.ldap.urls}") |
|||
private String ldapUrl; |
|||
@Value("${spring.ldap.base}") |
|||
private String ldapBase; |
|||
@Value("${spring.ldap.username}") |
|||
private String ldapUserDn; |
|||
@Value("${spring.ldap.password}") |
|||
private String ldapPassword; |
|||
|
|||
|
|||
|
|||
@Override |
|||
public void run(ApplicationArguments args) throws Exception { |
|||
//首先查询域控账号的所有数据 |
|||
Properties env = new Properties(); |
|||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); |
|||
env.put(Context.PROVIDER_URL, ldapUrl); |
|||
env.put(Context.SECURITY_AUTHENTICATION, "simple"); |
|||
env.put(Context.SECURITY_PRINCIPAL, ldapUserDn); |
|||
env.put(Context.SECURITY_CREDENTIALS, ldapPassword); |
|||
env.put(Context.REFERRAL, "ignore"); |
|||
env.put("ignorepartialresultexception", "true"); |
|||
|
|||
LdapContext ctx = null; |
|||
|
|||
//尝试解析数据 |
|||
try{ |
|||
// 创建DirContext对象,建立与LDAP服务器的连接 |
|||
ctx = new InitialLdapContext(env, null); |
|||
//调用方法读取数据 |
|||
Map<String, String> ldapAccountMap = LdapReadUtils.getAllLdapAccount(ctx, ldapBase); |
|||
|
|||
// 数据放到redis中去 |
|||
redisTemplate.opsForHash().putAll("ldapAccount", ldapAccountMap); |
|||
logger.info("域控账号缓存的数量:"+ldapAccountMap.size()); |
|||
|
|||
} catch (NamingException e) { |
|||
logger.error("Failed to connect to the LDAP server."); |
|||
} finally{ |
|||
ctx.close(); |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
package com.spring.modules.sys.task; |
|||
|
|||
import com.spring.common.utils.LdapReadUtils; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.scheduling.annotation.EnableScheduling; |
|||
import org.springframework.scheduling.annotation.Scheduled; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.naming.Context; |
|||
import javax.naming.NamingException; |
|||
import javax.naming.ldap.InitialLdapContext; |
|||
import javax.naming.ldap.LdapContext; |
|||
import java.io.IOException; |
|||
import java.util.Map; |
|||
import java.util.Properties; |
|||
|
|||
/** |
|||
* 定时同步域控账号信息到 Redis |
|||
*/ |
|||
@Component |
|||
@EnableScheduling |
|||
public class LdapAccountRefreshTask { |
|||
private static final Logger logger = LoggerFactory.getLogger(LdapAccountRefreshTask.class); |
|||
@Value("${spring.ldap.urls}") |
|||
private String ldapUrl; |
|||
@Value("${spring.ldap.base}") |
|||
private String ldapBase; |
|||
@Value("${spring.ldap.username}") |
|||
private String ldapUserDn; |
|||
@Value("${spring.ldap.password}") |
|||
private String ldapPassword; |
|||
|
|||
@Autowired |
|||
private RedisTemplate<String, Object> redisTemplate; |
|||
|
|||
@Scheduled(cron = "${task.data.refreshLdapAccountToRedis}") |
|||
public void refreshLdapAccountToRedis() throws NamingException { |
|||
//首先查询域控账号的所有数据 |
|||
Properties env = new Properties(); |
|||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); |
|||
env.put(Context.PROVIDER_URL, ldapUrl); |
|||
env.put(Context.SECURITY_AUTHENTICATION, "simple"); |
|||
env.put(Context.SECURITY_PRINCIPAL, ldapUserDn); |
|||
env.put(Context.SECURITY_CREDENTIALS, ldapPassword); |
|||
env.put(Context.REFERRAL, "ignore"); |
|||
|
|||
LdapContext ctx = null; |
|||
|
|||
//尝试解析数据 |
|||
try{ |
|||
// 创建DirContext对象,建立与LDAP服务器的连接 |
|||
ctx = new InitialLdapContext(env, null); |
|||
//调用方法读取数据 |
|||
Map<String, String> ldapAccountMap = LdapReadUtils.getAllLdapAccount(ctx, ldapBase); |
|||
|
|||
// 数据放到redis中去 |
|||
redisTemplate.opsForHash().putAll("ldapAccount", ldapAccountMap); |
|||
|
|||
} catch (NamingException | IOException e) { |
|||
logger.error("Failed to connect to the LDAP server."); |
|||
} finally{ |
|||
if (null != ctx){ |
|||
ctx.close(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue