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

时间:2016-02-17 22:19:33

标签: java ldap

问题

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

问题

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

    1. john在“cn = users,dc = ldap,dc = net”
    2. 中定义
    3. Calltaker在“cn = groups,dc = ldap,dc = net”
    4. 中定义
    5. 我正在查询TAM的ldap,来自java
    6. 使用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 个答案:

答案 0 :(得分:1)

  

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

您使用的任何一种过滤器,但要搜索的objectClass都是groupofUniqueNames(复数)。

  

我应该检查该搜索字符串给出的返回的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部分。