spring security 5失败,而具有相同凭据的单个组基失败我错过了什么?

vd8tlhqk  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(355)

这个问题是关于如何使用多个组搜索基而不是一个。
我使用了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密码。

wgmfuz8q

wgmfuz8q1#

在花了一些时间找出一个解决方案之后,我不得不承认,没有有效的方法来创建一个解决方案,即覆盖方法或类。
但是我偶然发现了一个springsecurity的变更请求,准确地说是在这个用例中,当需要检查多个组搜索库时。它是从springsecurityversion5.4.1(我相信)开始实现的,或者是在使用springstarter父版本2.4.2时包含的。
只需将此选项添加到身份验证方法中:

.groupSearchSubtree(true)

完整的身份验证更新方法示例如下所示:

@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{   
    auth
            .ldapAuthentication()
            .contextSource()
            .url(ldapUrl)
            .managerDn(ldapManagerDn)
            .managerPassword(ldapManagerPassword)
       .and()
            .userSearchFilter(ldapUserSearchFilter)
            .userSearchBase(ldapUserSearchBase)
            .groupSearchFilter(ldapGroupSearchFilter)
            .groupSearchBase(ldapGroupSearchBase)
            .groupSearchSubtree(true)
    ;

您可以看到,不再需要三个不同的节点,也不再需要转发更多的自定义上下文对象,只需为组搜索库添加父节点,然后让子树搜索完成其余的工作。
我自己想一个办法也许不错,但使用框架的集成解决方案肯定是更好的办法。

相关问题