【发布时间】:2012-11-16 13:17:38
【问题描述】:
如何获取所有 Active Directory 组(不仅与当前用户相关)?我正在使用弹簧安全 ldap。可以举一些例子吗?
【问题讨论】:
标签: java active-directory spring-security
如何获取所有 Active Directory 组(不仅与当前用户相关)?我正在使用弹簧安全 ldap。可以举一些例子吗?
【问题讨论】:
标签: java active-directory spring-security
Spring Security LDAP 非常适合验证用户,但如果你只需要查询 LDAP(在这种情况下适用于所有组),那么Spring LDAP (不要与Spring Security LDAP 混淆)更适合您的目的。
例子:
import static org.springframework.ldap.query.LdapQueryBuilder.query;
LdapTemplate ldapTemplate; // Injected via Spring
// Using Java 8 lambda expressions
ldapTemplate.search(
query().where("objectclass").is("group"),
(AttributesMapper<String>) attributes -> attributes.get("cn").get().toString()
);
【讨论】:
您可以做的是编写一个与DefaultLdapAuthoritiesPopulator 实现相匹配的LdapAuthoritiesPopulator 实现,并使用一个额外的方法来检索所有角色。
public class ExtendedLdapAuthoritiesPopulator
implements LdapAuthoritiesPopulator {
// Copy implementation of DefaultLdapAuthoritiesPopulator (omitted).
private String allAuthorityFilter
= "(&(objectClass=group)(objectCategory=group))";
public void setAllAuthorityFilter(String allAuthorityFilter) {
Assert.notNull(allAuthorityFilter,
"allAuthorityFilter must not be null");
this.allAuthorityFilter = allAuthorityFilter;
}
public final Collection<GrantedAuthority> getAllAuthorities() {
if (groupSearchBase == null) {
return new HashSet<>();
}
Set<GrantedAuthority> authorities = new HashSet<>();
if (logger.isDebugEnabled()) {
logger.debug("Searching for all roles with filter '"
+ allAuthorityFilter + "' in search base '"
+ groupSearchBase + "'");
}
Set<String> roles = ldapTemplate.searchForSingleAttributeValues(
groupSearchBase,
allAuthorityFilter,
new String[0],
groupRoleAttribute);
if (logger.isDebugEnabled()) {
logger.debug("Roles from search: " + roles);
}
for (String role : roles) {
if (convertToUpperCase) {
role = role.toUpperCase();
}
authorities.add(new SimpleGrantedAuthority(rolePrefix + role));
}
return authorities;
}
}
在您的 Spring 安全配置中,将 DefaultLdapAuthoritiesPopulator 更改为您的新实现。
一个额外的属性可以设置AllAuthorityFilter 过滤哪些组将被返回。
您可能希望您的实现只检索基于String 的角色名称,而不是GrantedAuthority 实例。
【讨论】:
这个类的默认值:
很有帮助
【讨论】:
获取所有 LDAP 组可能需要与获取登录用户的组不同的身份验证。可以使用 Spring LDAPTemplate。
import java.util.List;
import javax.naming.directory.SearchControls;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
public class LDAPListGroups {
public static void main(String[] args) throws Exception {
LdapContextSource ldapContextSource = new LdapContextSource();
//LDAP URL
ldapContextSource.setUrl("ldap://localhost:10389/dc=example,dc=com");
//Authenticate as User that has access to this node in LDAP
ldapContextSource.setUserDn("uid=admin,ou=system");
ldapContextSource.setPassword("secret");
ldapContextSource.afterPropertiesSet();
LdapTemplate ldapTemplate = new LdapTemplate(ldapContextSource);
ldapTemplate.afterPropertiesSet();
GroupAttributesMapper mapper = new GroupAttributesMapper();
SearchControls controls = new SearchControls();
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "groupOfNames"));
List<Group> groups = ldapTemplate.search("ou=groups", filter.encode(), controls, mapper);
for (Group group:groups)
{
System.out.println(group.getLongID());
}
}
}
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.support.LdapEncoder;
public class GroupAttributesMapper implements AttributesMapper<Group> {
public Group mapFromAttributes(Attributes attributes) throws NamingException {
Group groupObject = new Group(attributes.get("cn").get().toString().toUpperCase());
NamingEnumeration<?> it = attributes.get("member").getAll();
while (it.hasMoreElements())
{
String elem = (String) it.next();
elem = elem.substring(elem.indexOf("cn=")+3);
elem = elem.substring(0,elem.indexOf(","));
elem = LdapEncoder.nameDecode(elem);
groupObject.addMember(elem);
}
return groupObject;
}
}
【讨论】: