如何检查用户是不是在 LDAP 组中

Posted

技术标签:

【中文标题】如何检查用户是不是在 LDAP 组中【英文标题】:How to check if a user is in an LDAP group如何检查用户是否在 LDAP 组中 【发布时间】:2016-05-29 21:04:39 【问题描述】:

问题

我想查看用户“john”是否在组“Calltaker”中。我似乎无法在我的搜索过滤器上找到正确的语法来检查特定组中的特定用户。我可以列出组中的所有用户,以验证所需的用户是否存在。

问题

    ldap 搜索过滤器确定特定用户是否在特定组中(在 Tivoli Access Manager 中)的正确语法是什么? 我应该如何检查由该搜索字符串给出的返回的 LDAPEntry 对象,以查看用户是否在组中?

信息

    john 在“cn=users,dc=ldap,dc=net”中定义 Calltaker 在“cn=groups,dc=ldap,dc=net”中定义 我正在从 java 查询 TAM 的 ldap

使用 searchfilter 为"cn=Calltaker" 我可以打印出搜索结果,这样调用 nextEntry.toString 就会包含用户列表。请参阅下面的示例 1

这是我尝试过的一些不起作用的搜索过滤器(又名 searchResults.next() 会引发错误):

(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))
(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)

示例 1) 仅搜索组,使用 searchFilter="cn=Calltaker",验证它是否包含用户:

System.out.println(nextEntry.toString()); //added newlines for readability
 nextEntry: 
 LDAPEntry: 
 cn=Calltaker,cn=groups,dc=ldap,dc=net; 
 LDAPAttributeSet: 
 LDAPAttribute: type='objectclass', values='groupOfUniqueNames','top' 
 LDAPAttribute: type='uniquemember', 
  values=
     'uid=placeholder,cn=users,dc=ldap,dc=net',
     'secAuthority=default',
     'uid=john,cn=users,dc=ldap,dc=net',
     'uid=sally,cn=users,dc=ldap,dc=net', ....etc

代码:

public boolean isUserInGroup(username)
    boolean userInGroup = false;

    String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
    String searchBase = "cn=groups,dc=ldap,dc=net";
    int searchScope = LDAPConnection.SCOPE_SUB; 
    searchFilter = "(&(objectclass=ePerson)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";

    //Connect
    LDAPConnection lc = connect(hosts);
    lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
    lc.getAuthenticationDN();

    LDAPSearchResults searchResults = lc.search(searchBase,
            searchScope, 
            searchFilter, 
            null,           // return all attributes
            false);         // return attrs and values

    while (searchResults.hasMore()) 
        LDAPEntry nextEntry = null;
        try 
            nextEntry = searchResults.next();
         catch (LDAPException e) 
            // Exception is thrown, go for next entry
            if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
                break;
            else
                continue;
        
        //TODO some check to verify nextEntry shows the user in the group
        userInGroup = true;
        LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
        Iterator<LDAPAttribute> allAttributes = attributeSet.iterator();
        while (allAttributes.hasNext()) 
            LDAPAttribute attribute = (LDAPAttribute) allAttributes.next();
            String attributeName = attribute.getName();
            System.out.println("found attribute '" + attributeName + "' with value '" + attribute.getStringValue() + "'");
        
    
    lc.disconnect();
return userInGroup;

** 编辑 **

实施来自 EJP 的答案,将 searchBase 更改为包含组

有效的代码:

private static final String admin_username = "foo";
private static final String[] hosts = new String[]"foohost.net";
public boolean isUserInGroup(String username, String group)
    boolean userInGroup = false;

    String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
    String searchBase = "cn=" + group + "," + "cn=groups,dc=ldap,dc=net";
    int searchScope = LDAPConnection.SCOPE_SUB; 
    searchFilter = "(&(objectclass=groupOfUniqueNames)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";

    //Connect
    LDAPConnection lc = connect(hosts);
    lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
    lc.getAuthenticationDN();

    LDAPSearchResults searchResults = lc.search(searchBase,
            searchScope, 
            searchFilter, 
            null,           // return all attributes
            false);         // return attrs and values

    while (searchResults.hasMore()) 
        LDAPEntry nextEntry = null;
        try 
            nextEntry = searchResults.next();
         catch (LDAPException e) 
            // Exception is thrown, go for next entry
            if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
                break;
            else
                continue;
        
        //A result was found, therefore the user is in the group
        userInGroup = true;
    
    lc.disconnect();
    return userInGroup;

【问题讨论】:

【参考方案1】:

ldap 搜索过滤器确定特定用户是否在特定组中(在 Tivoli Access Manager 中)的正确语法是什么?

您使用的任一过滤器,但要搜索的 objectClassgroupofUniqueNames(复数)。

我应该检查该搜索字符串给出的返回的 LDAPEntry 对象以查看用户是否在组中?

什么都没有。他将是,否则该组将不会在搜索中返回。您需要做的就是检查搜索结果是否为非空。

这是我尝试过的一些不起作用的搜索过滤器(又名 searchResults.next() 会引发错误):

抛出什么错误?

(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))

除了groupOfUniqueName,这没什么问题。您应该使用像 0 这样的搜索过滤器参数,而不是将它们构建到搜索字符串中。

(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))

这将在cn=users 子树中搜索一个组。除非您在cn=users 下有组,否则它不会起作用,这似乎不太可能。

(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)

这将选择非组。你不希望这样:你需要 objectClass 部分。

【讨论】:

澄清搜索过滤器语法有很大帮助,我还必须更改搜索库以包含该组。例如"cn=Calltaker,cn=groups,dc=ldap,dc=net"

以上是关于如何检查用户是不是在 LDAP 组中的主要内容,如果未能解决你的问题,请参考以下文章

如何检查用户是不是存在于 LDAP 上

DNN 检查用户是不是在角色组中

在Plone 4.1中,如何从特定组中获取LDAP用户?

java - 如何使用给定的LdapContext检查ldap中的用户密码?

使用 Power Automate 检查 Office 365 组中是不是存在 Teams/SharePoint 用户

在关闭之前检查 Auto Scaling 组中的 EC2 实例是不是有任何用户在使用它