我想找到用户所属的所有组,包括嵌套组。 就像用户是A1组的一部分而A1组是A的一部分一样,那么我也希望得到A.
以下是代码,我尝试了variuos filterstrings ...但没有给出预期的输出。
String samAccountName = "group";
String searchFilter = "(&(objectclass=user)(memberof: 1.2.840.113556.1.4.1941:="+samAccountName+"))";
//String searchFilter = "(&(objectCategory=person)(memberOf=CN="+samAccountName+"))";
//String searchFilter = "(&(objectcategory=user)(memberof=CN="+samAccountName+",OU=Users,DC=new,DC=com))";
String searchBase = "DC=new,DC=com";
NamingEnumeration answer = ctx.search(searchBase, searchFilter, ontrols);
List rolesList = new ArrayList();
while(answer.hasMoreElements()){
SearchResult sr = (SearchResult)answer.next();
...
感谢任何帮助。
答案 0 :(得分:1)
我希望您必须递归搜索用户的memberOf属性列表。例如如果用户具有ldapsearch
调用的以下ldif样式结果:
cn: user1
memberOf: CN=group1,DC=foo,DC=example,DC=com
memberOf: CN=group2,DC=foo,DC=example,DC=com
..然后你会想要以递增的ldap搜索递归查找group1
和group2
,依此类推这些组成员的组。
我现在正在做类似的事情,但是在perl中,并从Active Directory获取所有组的所有成员的平面列表。 AD使用objectClass: group
而OpenLDAP倾向于使用objectClass: groupOfUniqueNames
或objectClass: posixGroup
,具体取决于用途(unix-y客户端的posix组,如Linux box,groupOfUniqueNames组,以获取更多一般信息。)完全取决于客户使用目录中的信息。)
编辑:在AD中还应该有一个名为tokenGroups
的属性,其中包含用户的安全组的SID,但这对我不起作用。我猜它是可选的,并没有在我的网站的AD服务器上启用。
答案 1 :(得分:0)
下面的代码可以找到用户所属的组列表。正在使用正在使用的LDAP实现
package pack;
import static javax.naming.directory.SearchControls.SUBTREE_SCOPE;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import com.sun.jndi.ldap.LdapCtxFactory;
class App4
{
public static void main(String[] args)
{
String username = "userName";
String password = "password";
String serverName = "server";
String domainName = "comp.BIZ";
System.out.println("Authenticating " + username + "@" + domainName
+ " through " + serverName + "." + domainName);
// bind by using the specified username/password
Hashtable<String,String> props = new Hashtable<String,String>();
String principalName = username + "@" + domainName;
props.put(Context.SECURITY_PRINCIPAL, principalName);
props.put(Context.SECURITY_CREDENTIALS, password);
DirContext context;
try {
context = LdapCtxFactory.getLdapCtxInstance("ldap://" + serverName
+ "." + domainName + '/', props);
System.out.println("Authentication succeeded!");
// locate this user's record
SearchControls controls = new SearchControls();
controls.setSearchScope(SUBTREE_SCOPE);
NamingEnumeration<SearchResult> renum = context.search(
toDC(domainName), "(& (userPrincipalName=" + principalName
+ ")(objectClass=user))", controls);
if (!renum.hasMore())
{
System.out.println("Cannot locate user information for "
+ username);
System.exit(1);
}
SearchResult result = renum.next();
List<GrantedAuthority> groups = new ArrayList<GrantedAuthority>();
Attribute memberOf = result.getAttributes().get("memberOf");
if (memberOf != null)
{// null if this user belongs to no group at
// all
for (int i = 0; i < memberOf.size(); i++)
{
Attributes atts = context.getAttributes(memberOf.get(i)
.toString(), new String[] { "CN" });
Attribute att = atts.get("CN");
groups.add(new GrantedAuthorityImpl(att.get().toString()));
}
}
context.close();
System.out.println();
System.out.println("User belongs to: ");
Iterator<GrantedAuthority> ig = groups.iterator();
while (ig.hasNext())
{
System.out.println(" " + ig.next().toString());
}
} catch (AuthenticationException a)
{
System.out.println("Authentication failed: " + a);
System.exit(1);
} catch (NamingException e)
{
System.out
.println("Failed to bind to LDAP / get account information: "
+ e);
System.exit(1);
}
}
private static String toDC(String domainName)
{
StringBuilder buf = new StringBuilder();
for (String token : domainName.split("\\."))
{
if (token.length() == 0)
continue; // defensive check
if (buf.length() > 0)
buf.append(",");
buf.append("DC=").append(token);
}
return buf.toString();
}
}
答案 2 :(得分:0)
String searchFilter =“(&amp;(objectClass = person)(samaccountname =”+ userName +“))”
我修改了searchFilter并且它有效。
答案 3 :(得分:0)
在 LDAP 中,我们可以在建立连接后查询用户是否属于给定组,您可以使用 member 或 memberOf 属性进行查询。
Query for memberOf Attribute :
filter used : (&(Group Member Attribute=Group DN)(objectClass=Group Object class))
Ex : (&(memberOf=CN=group,ou=qa_ou,dc=ppma,dc=org)(objectClass=group))
Using member Attribute :
filter used : (&(Group Member Attribute=User DN)(objectClass=Group Object class))
Ex : (&(member=CN=user,ou=qa_ou,dc=ppma,dc=org)(objectClass=group))
但是您必须使用用户的 member 或 memberOf 属性列表进行递归搜索。例如如果用户具有以下组层次结构:
cn:user1 memberOf: CN=group1,DC=foo,DC=example,DC=com memberOf: CN=group2,DC=foo,DC=example,DC=com
然后,您需要使用额外的 LDAP 搜索递归查找 group1 和 group2,对这些组所属的组依此类推。
以下是查询用户所属的所有嵌套组的示例代码:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
public class MemberDemo {
private static final String contextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
private static final String connectionURL = "ldap://10.224.243.133:389";
private static final String connectionName = "CN=administrator,CN=users,DC=ppma,DC=org";
private static final String connectionPassword = "Conleyqa12345";
public static int nestLevel = 3;
public static int level = 1;
// Optional
private static final String authentication = null;
private static final String protocol = null;
private static String userBase = "OU=qa_OU,DC=ppma,DC=org";
public static void main(String[] args) throws NamingException {
long start = System.currentTimeMillis();
Hashtable<String, String> env = new Hashtable<String, String>();
// Configure our directory context environment.
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
env.put(Context.PROVIDER_URL, connectionURL);
env.put(Context.SECURITY_PRINCIPAL, connectionName);
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
if (authentication != null)
env.put(Context.SECURITY_AUTHENTICATION, authentication);
if (protocol != null)
env.put(Context.SECURITY_PROTOCOL, protocol);
InitialDirContext context = new InitialDirContext(env);
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
Set<String> traversedGroups = new HashSet<String>();
Set<String> relatedGroups = new HashSet<String>();
List<String> tempParentColl = new CopyOnWriteArrayList<String>();
List<String> tempGroups = new ArrayList<String>();
String loginUser = "CN=qa20Nest,OU=qa_OU,DC=ppma,DC=org";
String filter = "(&(member=" + loginUser + ")(objectClass=group))";
tempGroups = findNestedGroups(tempGroups, context, filter, loginUser, constraints,
tempParentColl, traversedGroups, getUserName(loginUser));
relatedGroups.addAll(tempGroups);
System.out.println("Parent Groups :");
for (String group : relatedGroups) {
System.out.println(group);
}
long end = System.currentTimeMillis();
long elapsedTime = end - start;
System.out.println("Total time taken in sec : " + elapsedTime / 1000);
}
@SuppressWarnings("rawtypes")
public static List<String> findNestedGroups(List<String> tempGrpRelations, InitialDirContext context, String filter,
String groupName, SearchControls constraints, List<String> tempParentColl, Set<String> traversedGrp,
String groupIdentifier) {
NamingEnumeration results;
try {
traversedGrp.add(groupName);
results = context.search(userBase, filter, constraints);
// Fail if no entries found
if (results == null || !results.hasMore()) {
System.out.println("No result found for :" + groupName);
if (tempParentColl.isEmpty()) {
return tempGrpRelations;
} else {
tempParentColl.remove(groupName);
}
}
while (results.hasMore()) {
SearchResult result = (SearchResult) results.next();
System.out.println("DN - " + result.getNameInNamespace());
tempParentColl.add(result.getNameInNamespace());
tempGrpRelations.add(result.getNameInNamespace());
}
Iterator<String> itr = tempParentColl.iterator();
while (itr.hasNext()) {
String groupDn = itr.next();
String nfilter = "(&(member=" + groupDn + ")(objectClass=group))";
tempParentColl.remove(groupDn);
if (!traversedGrp.contains(groupDn)) {
findNestedGroups(tempGrpRelations, context, nfilter, groupDn, constraints, tempParentColl,
traversedGrp, getUserName(groupDn));
}
}
} catch (NamingException e) {
e.printStackTrace();
}
return tempGrpRelations;
}
public static String getUserName(String cnName) {
String name = cnName.substring(cnName.indexOf("CN=")).split(",")[0].split("=")[1];
return name;
}
}