1。创建测试用户和组
测试用户:
dn: uid=testuser,ou=users,ou=open,ou=groups,dc=drm,dc=dbs
givenName: testuser
objectClass: person
objectClass: inetorgperson
objectClass: organizationalPerson
objectClass: top
uid: testuser
cn: testuser
sn: testuser
测试组
dn: cn=testgroup,ou=roles,ou=open,ou=groups,dc=drm,dc=dbs
objectClass: top
objectClass: groupofUniqueNames
description: testgroup
cn: testgroup
UniqueMember:uid=testuser,ou=users,ou=open,ou=groups,dc=drm,dc=dbs
2。使用ismemberof 查询用户和组
LDAP下不管是动态组还是静态组,都可以使用ismemberof虚拟属性来实现以下三个功能
1)To List All Members in Your Static Group ---查询组下的所有用户
这个最简单,只要设置过滤器条件为"(isMemberOf=cn=testgroup,ou=roles,ou=open,ou=groups,dc=drm,dc=dbs)"就可以了
SearchControls sc = new SearchControls();
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
try {
DirContext dirctx=getLdapContext();
NamingEnumeration iter = dirctx.search(searchRoot, "(isMemberOf=cn=testgroup,ou=roles,ou=open,ou=groups,dc=drm,dc=dbs)",sc);
while (iter != null && iter.hasMoreElements()) {
SearchResult result = (SearchResult) iter.next();
String userDN = result.getNameInNamespace();
System.out.println(userDN);
}
dirctx.close();
} catch (Exception e) {
e.printStackTrace();
}
2)To List All Groups to Which a User Is a Member ---查询用户所属的所有组
这里要注意一点,关于虚拟属性(ismemberof),在查询时需要明确指定,否则不会返回该属性,这里通过调用SearchContrls的setReturningAttributes方法来实现
SearchControls sc = new SearchControls();
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
String returnedAtts[] = {"isMemberOf"};
sc.setReturningAttributes(returnedAtts);
try {
DirContext dirctx=getLdapContext();
NamingEnumeration iter = dirctx.search(ldapRoot, "(uid=testuser)",sc);
if (iter != null && iter.hasMoreElements()) {
SearchResult result = (SearchResult) iter.next();
Attributes attrs=result.getAttributes();
Attribute oneAttr=attrs.get("ismemberof");
NamingEnumeration groupIter=oneAttr.getAll();
while(groupIter.hasMoreElements()){
String groupDn=(String)groupIter.next();
System.out.println(groupDn);
}
}
dirctx.close();
} catch (Exception e) {
e.printStackTrace();
}
3)To Determine Whether a User is a Member of a Group---查看用户是否属于组成员
这个比较简单,在1)的基础上增加过滤条件为
"(&(uid=testuser)(isMemberOf=cn=testgroup,ou=roles,ou=open,ou=groups,dc=drm,dc=dbs))"
如果用户在组下,则返回整个用户节点
SearchControls sc = new SearchControls();
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
try {
DirContext dirctx=getLdapContext();
NamingEnumeration iter = dirctx.search(ldapRoot, "(&(uid=testuser)(isMemberOf=cn=testgroup,ou=roles,ou=open,ou=groups,dc=drm,dc=dbs))",sc);
if (iter != null && iter.hasMoreElements()) {
SearchResult result = (SearchResult) iter.next();
// Attributes attrs=result.getAttributes();
String userDN = result.getNameInNamespace();
System.out.println(userDN);
}else{
System.out.println("user not in group");
}
dirctx.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
3.关于角色。opends官网明确说明不支持dsee中的角色机制(说是非标准化),但是可以通过设置nsRole虚拟属性兼容那边的角色管理
1)设置方法可以参考
https://www.opends.org/wiki/page/SimulatingDSEERolesInOpenDS
大致是把角色看成了一个动态组
2)设置成功后可以使用nsRole作为虚拟属性来实现类似ismemberof的功能。需要注意的是nsRoleDn和nsRole的区别
nsRoleDn类似动态组的memberURL是写在实体节点下的属性
nsRole类似虚拟属性ismemberof,客户端请求这个属性时,它会根据需要生成查询结果
3)要注意的是opends与dsee另一个区别在于定义aci是,通配符“*”在opends下是不包含虚拟属性操作的,也就是说如果不明确指定nsRole,并授予权限,而用“*”号代替,被授权用户也是无法使用这个操作的。
4)其他用法通ismemberof
4.另外关于Filter的写法可参考
https://www.opends.org/wiki/page/HowToSearchInOpenDS