这个问题是关于如何使用多个组搜索基而不是一个。
我使用了samaddico提供的一个示例(simplespringsecurity+ldap示例),用提供的server/user/ldap配置文本将其修改为单组搜索库。它使用一个服务帐户连接到ldap,然后用户尝试对某些简单的web页面进行身份验证。这种方法可以工作,但缺乏从搜索树中的不同组收集成员资格/角色的能力。
SpringSecurity提供类 LdapContextSource
以及 MultipleLdapAuthoritiesPopulator
允许在不同位置搜索角色。下面是导致以下错误的代码:
ldap配置:
* Create an implementation of org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator which can call
multiple instances of LdapAuthoritiesPopulator.
* Then create one LdapAuthoritiesPopulatorfor each 'groupSearchBase' that I wanted to query.
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
LdapContextSource contextSource = contextSource();
MultipleLdapAuthoritiesPopulator multipleLdapAuthoritiesPopulator = new MultipleLdapAuthoritiesPopulator(
new DefaultLdapAuthoritiesPopulator(contextSource, ldapGroupSearchBaseA),
new DefaultLdapAuthoritiesPopulator(contextSource, ldapGroupSearchBaseB),
new DefaultLdapAuthoritiesPopulator(contextSource, ldapGroupSearchBaseC));
auth
.ldapAuthentication()
.contextSource(contextSource)
.ldapAuthoritiesPopulator(multipleLdapAuthoritiesPopulator)
.userSearchFilter(ldapUserSearchFilter)
.userSearchBase(ldapUserSearchBase);
}
class MultipleLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
private List<LdapAuthoritiesPopulator> authoritiesPopulators;
public MultipleLdapAuthoritiesPopulator(LdapAuthoritiesPopulator...authoritiesPopulators) {
this.authoritiesPopulators = Arrays.asList(authoritiesPopulators);
}
@Override
public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
List<GrantedAuthority> grantedAuthorities = authoritiesPopulators.stream()
.map(authPopulator -> authPopulator.getGrantedAuthorities(userData, username))
.flatMap(Collection::stream)
.collect(Collectors.toList());
return grantedAuthorities;
}
}
/**
* Creates context source object instead of configuring it with AuthenticationBuilder
* @return Context source object used for accessing ldap server
*/
@Bean
public LdapContextSource contextSource() {
LdapContextSource contextSource= new LdapContextSource();
contextSource.setUrl(ldapUrl);
contextSource.setUserDn(ldapManagerDn);
contextSource.setPassword(ldapManagerPassword);
contextSource.afterPropertiesSet();
return contextSource;
}
会话配置:
/**
* This is essential to make sure that the Spring Security session registry is notified when the session is destroyed.
* @return
*/
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
spring应用程序告诉我,我的服务帐户已成功连接到ldap服务器。
DEBUG 17220 --- [nio-8080-exec-5] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@c1e15be1: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 127.0.0.1; SessionId: 0A82CE8FA4FB9EB248D756EEE8134CAE; Granted Authorities: ROLE_ANONYMOUS
当找到的用户正在尝试绑定时,会抛出错误:
DEBUG 17220 --- [nio-8080-exec-8] o.s.s.l.a.BindAuthenticator : Failed to bind as CN=familyName\, name,OU=Group: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090453, comment: AcceptSecurityContext error, data 52e, v3839 ]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090453, comment: AcceptSecurityContext error, data 52e, v3839 ]
DEBUG 17220 --- [nio-8080-exec-8] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
总而言之:我的凭据对于单个组基来说是正确的,而不使用 LdapContextSource
以及 MultipleLdapAuthoritiesPopulator
. 但是身份验证过程似乎没有为具有多个组基的用户提供enteret密码。
1条答案
按热度按时间wgmfuz8q1#
在花了一些时间找出一个解决方案之后,我不得不承认,没有有效的方法来创建一个解决方案,即覆盖方法或类。
但是我偶然发现了一个springsecurity的变更请求,准确地说是在这个用例中,当需要检查多个组搜索库时。它是从springsecurityversion5.4.1(我相信)开始实现的,或者是在使用springstarter父版本2.4.2时包含的。
只需将此选项添加到身份验证方法中:
完整的身份验证更新方法示例如下所示:
您可以看到,不再需要三个不同的节点,也不再需要转发更多的自定义上下文对象,只需为组搜索库添加父节点,然后让子树搜索完成其余的工作。
我自己想一个办法也许不错,但使用框架的集成解决方案肯定是更好的办法。