【问题标题】:How can you get all users related to a user ( directly & indirectly )如何获取与用户相关的所有用户(直接或间接)
【发布时间】:2020-07-12 07:18:26
【问题描述】:

我有一个问题,我必须使用自定义 LDAP 属性获取与用户相关的所有用户,现在我只能通过使用带有查询的递归函数来实现这一点,每次调用都会不断增长,我知道这一点不会扩展,有没有更好的方法来实现这一点。

这是我使用的代码。

/*
 * at start accumlatedUsers === usersToBeSearched accumlatedUsers will be
 * updated
 */
public void GetSubordinatesRecurisve(ArrayList<String> usersToBeSearched, ArrayList<String> accumlatedUsers)
        throws NamingException {

    String searchFilter = "(&(ObjectCategory=User)(|";
    for (String user : usersToBeSearched) {
        searchFilter += "(supeirorName=" + user + ")";
    }
    searchFilter += "))";

    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    NamingEnumeration<SearchResult> results = ldapContext.search(ldapSearchBase, searchFilter, searchControls);

    ArrayList<String> usersFounded = new ArrayList<String>();
    SearchResult searchResult = null;
    while (results.hasMoreElements()) {
        searchResult = (SearchResult) results.nextElement();
        usersFounded.add((String) searchResult.getAttributes().get("sAMAccountName").get());
    }

    accumlatedUsers.addAll(usersFounded);

    if (usersFounded.size() != 0) {
        this.GetSubordinatesRecurisve(usersFounded, accumlatedUsers);
    }

    return;
}

谢谢。

【问题讨论】:

    标签: java active-directory ldap


    【解决方案1】:

    是的,问题是您的查询ldapContext.search 中的用户数量将呈指数增长,因此根本无法扩展。例如,第 1 次查询 1 位用户,第 2 次查询 3 位用户,第 3 次查询 9 位用户,以此类推。

    与单个用户相关的用户可以被视为一棵树(如果没有循环)。遍历树最常见的方法是深度优先搜索 (DFS) 或面包优先搜索 (BFS) 算法。如果您的目标是找到 ALL 与某个用户相关的用户,那么任何一个选项都可以。

    DFS(或 BFS)比您的解决方案更具可扩展性,因为它每次都会使用 1 个用户查询 LDAP。

    我无法测试您的方法,但我正在向您展示如何实现 DFS:

    // ...
    accumlatedUsers.addAll(usersFounded);
    
    for(String userFounded : usersFounded){
        if(!visited.contains(userFounded)){
            visited.add(userFounded);
            List<String> singleUserList = new ArrayList<>();
            singleUserList.add(userFounded);
            this.GetSubordinatesRecurisve(singleUserList, accumlatedUsers);
        }
    }
    
    return;
    

    注意访问过的列表,它是为了防止您的用户图中出现循环。

    【讨论】:

    • 谢谢,但我想我仍然会遇到同样的问题,例如如果我有 10000 个相关用户,那么我将不得不提出 10000 个请求,这是否可行?
    • 10k 请求对于 LDAP 来说并不算多,但如果您认为这是瓶颈,它肯定可以改进。 LDAP 是本地的还是远程的? LDAP 中有多少用户?
    • AD 在本地环境中的另一台机器上,我认为大约有 5000 个用户,但我不知道未来。
    • 好的。您多久调用一次 GetSubordinatesRecurisve?如果是每天一次,那很好。如果经常发生,那么您可以缓存结果(因为我认为它不会经常更改)。我会选择一个简单的解决方案 (DFS),并最终通过缓存对其进行改进,而不是现在过度优化。如果您认为它有用,请点赞;)
    猜你喜欢
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多