4

使用 UnboundID LDAP sdk,如何获取特定用户所属的所有 LDAP 组?(我真的很感激一些示例代码)。

4

2 回答 2

3

我也有同样的问题。但是,迈克尔的解决方案对我不起作用,因为它不能递归地工作。

显然,有一个“神奇”的 AD 查询可以递归地获取所有组,请参阅 Find Recursive Group Membership (Active Directory) using C#如何过滤包含特定用户的组的 LDAP 查询?

虽然我们的 AD 管理员已使用 ldifde 从命令行获取所有组,但我无法让查询与 UnboundID 一起使用。我们的 CN 内部有空格,UnboundID 添加了一个奇怪的“5c”——但即使有一个没有空格的(技术)用户,我也没有得到任何结果。


无论如何,这是我的工作(和低效)源代码(使用谷歌番石榴)。我省略了一些方法和常量,我想你可以猜到常量的值OBJECT_CLASS是什么:-)

  /**
   * Gets the groups for a user which is identified by the filter.
   * @param filter The filter that identifies the user
   * @return The groups for the user
   */
  private List<String> getGroups(final Filter filter) {
    LDAPConnection connection = null;
    try {
      connection = getConnection();

      String userDN = getUserDN(connection, filter);
      if (userDN == null) {
        return Collections.emptyList(); // No user found
      }

      Multimap<String, String> groupsByDN = ArrayListMultimap.create();
      getGroupsRecursively(connection, userDN, groupsByDN);
      Set<String> groups = new HashSet<>(groupsByDN.values());
      for (String dn : groupsByDN.keySet()) {
        // The user is not a group...
        if (!dn.equals(userDN)) {
          DN distinguishedName = new DN(dn);
          for (RDN rdn : distinguishedName.getRDNs()) {
            if (rdn.hasAttribute(CN)) {
              groups.add(rdn.getAttributeValues()[0]);
              break;
            }
          }
        }
      }
      return new ArrayList<String>(groups);
    } catch (LDAPException e) {
      throw new RuntimeException("Can't search roles for " + filter, e);
    } finally {
      if (connection != null) {
        connection.close();
      }
    }
  }

  /**
   * Since LDAP groups are stored as a tree, this fetches all groups for a user, starting with the user's DN and then
   * fetching every group's groups and so on.
   * @param connection The LDAP connection
   * @param distinguishedName The distinguished name for which groups are searched
   * @param groupsByDN Contains a distinguished name as key and its group name as result; keys are only searched once!
   * @throws LDAPSearchException if the LDAP search fails
   */
  private void getGroupsRecursively(final LDAPConnection connection, final String distinguishedName,
      final Multimap<String, String> groupsByDN) throws LDAPSearchException {
    if (!groupsByDN.containsKey(distinguishedName)) {
      Filter groupFilter = Filter.createANDFilter(Filter.createEqualityFilter(OBJECT_CLASS, GROUP),
          Filter.createEqualityFilter(MEMBER, distinguishedName));
      SearchResult result = getSearchResult(connection, groupFilter, CN);
      List<SearchResultEntry> searchResults = result.getSearchEntries();
      for (SearchResultEntry searchResult : searchResults) {
        String groupName = searchResult.getAttributeValue(CN);
        groupsByDN.put(distinguishedName, groupName);
        getGroupsRecursively(connection, searchResult.getDN(), groupsByDN);
      }
    }
  }
于 2013-07-09T12:35:40.890 回答
1

下面的函数仅适用于 Active Directory,因为它生成成员属性 memberOf。如果我能找到通用 LDAP 的方法,我会添加它。

    Entry   userEntry = ldapConnection.getEntry(userDN);

    List<Entry> entryList = new ArrayList();
    String[] memberValues = userEntry.getAttributeValues("memberOf");
    if (memberValues != null) {
        DNEntrySource entrySource = new DNEntrySource(ldapConnection, memberValues);
        while (true) {
            Entry memberEntry = entrySource.nextEntry();
            if (memberEntry == null) {
                break;
            }

            entryList.add(memberEntry);
        }
    }

    return entryList;
于 2013-07-02T15:45:15.823 回答