我们正在编写允许Active Directoryauthentication机制的软件工具。 它定期在AD和工具之间同步用户组。 我们的一些客户观察到,在同步操作期间,AD服务器上的CPU负载很高。
我查找了可能导致问题的原因。 其中之一是嵌套组。
另外我在互联网上也发现其他人也有这样的问题,当他们改变AD端口的时候问题就消失了。 我想知道最后一个场景是否真实(对于我来说,更改AD端口可能会解决问题有点奇怪),以及是否还有其他常见原因可能会导致问题。
我们使用以下查询来同步:
(&(memberof:1.2.840.113556.1.4.1941:=group_DN)(objectclass=user)(!(objectclass=computer))
不要对recursion组成员资格使用LDAP匹配规则传递评估。 这是非常缓慢的,尤其是在大型目录/组织成员的情况下。
http://dunnry.com/blog/TransitiveLinkValueFilterEvaluation.aspx
https://stackoverflow.com/questions/9534669/improving-recursive-active-directory-function
所以事实certificate,这个问题确实是与嵌套组。 我将recursion逻辑“移动”到客户端,并将运行时间缩短了10倍。 我不知道networkingstream量会增加多less。 无论如何,这里是我使用的代码片段,以防万一,如果有人感兴趣:
public Set<String> getUsersInGroup(String groupDN) throws NamingException { Set<String> ret = new HashSet<>(); Queue<String> bfsQueue = new LinkedList<>(); bfsQueue.add(groupDN); Set<String> visitedGroups = new HashSet<>(); LdapContext ctx = getLdapContext(MAX_SEARCH_TIME, false); String[] attrIDs = getUserReturnAttrs().toArray(new String[0]); while (!bfsQueue.isEmpty()) { String current = bfsQueue.element(); bfsQueue.remove(); visitedGroups.add(current); String userFilter = "(&(objectclass=user)(!(objectclass=computer)))"; String groupFilter = "(&(objectclass=group)(!(objectclass=computer)))"; String memberOfFilter = String.format("(memberof=%s)", current); String userQuery = String.format("(&%s%s)", memberOfFilter, userFilter); String groupQuery = String.format("(&%s%s)", memberOfFilter, groupFilter); Set<SearchResult> groups = search(ctx, getSearchBase(), groupQuery, SearchControls.SUBTREE_SCOPE, new String[] { "distinguishedName" }, NO_COUNT_LIMIT); for (SearchResult g : groups) { Attributes attrs = g.getAttributes(); String gDN = parseAttribute(attrs, "distinguishedName"); if (!visitedGroups.contains(gDN)) bfsQueue.add(gDN); } Set<SearchResult> users = search(ctx, getSearchBase(), userQuery, SearchControls.SUBTREE_SCOPE, attrIDs, NO_COUNT_LIMIT); for (SearchResult u : users) { Attributes attrs = u.getAttributes(); String uDN = parseAttribute(attrs, "userPrincipalName"); ret.add(uDN); } } return ret; }