如何在使用Spring Security和LDAP进行身份验证时检索权限/角色?

chhqkbe1  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(243)

首先,我想说的是,我并不完全了解LDAP,所以如果我需要提供更多关于LDAP的信息,请这样说。
我有一个spring Boot 应用程序(Java 17,spring Boot 3.2.0),它配置了LDAP身份验证:

@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().fullyAuthenticated()
                .and()
                .httpBasic(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
        LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
        factory.setUserSearchFilter("(userPrincipalName={0})");
        factory.setUserDnPatterns("userPrincipalName={0}");

        return factory.createAuthenticationManager();
    }

字符串
到目前为止一切顺利。身份验证工作正常,速度很快。但现在我想检索用户所属的组/权限。如果从LDAP客户端查看LDAP(我使用的是LDAP Admin,我使用的是与Sping Boot 应用程序中相同的用户进行身份验证),我可以看到以下内容:x1c 0d1x
如果我运行查询(member=cn=Eriksson,Viktor - e-bolvier,ou=External Users,ou=....,dc=internal),我会得到这个:

所以我添加了这些行:

@Bean
    AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource, LdapAuthoritiesPopulator authorities) {
        .....
        factory.setLdapAuthoritiesPopulator(authorities);
        .....
    }

    @Bean
    LdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) {
        String groupSearchBase = "";
        DefaultLdapAuthoritiesPopulator authorities =
                new DefaultLdapAuthoritiesPopulator(contextSource, groupSearchBase);
        authorities.setGroupSearchFilter("(member=cn=Eriksson\\, Viktor - e-bolvier,ou=External Users,ou=.....)");

        return authorities;
    }


我知道过滤器应该是这样的(member={0}),但由于某种原因,它将我的昵称编码为:member=cn=Eriksson\5c,Viktor.
添加这些行后,它开始崩溃并说:

org.springframework.ldap.PartialResultException: Unprocessed Continuation Reference(s)
    at 
org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:218) ~[spring-ldap-core-3.2.0.jar:3.2.0]
    at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:375) ~[spring-ldap-core-3.2.0.jar:3.2.0]
....


在谷歌上搜索之后,我发现了几个建议将referral设置为“follow '”的答案。所以我将这些行添加到Application-class中:

@Autowired
private ApplicationContext applicationContext;

@PostConstruct
    private void setReferralForContext() {
        LdapTemplate ldapTemplate = applicationContext.getBean(LdapTemplate.class);// necessary for LdapContextSource to be created
        LdapContextSource ldapContextSource = applicationContext.getBean(LdapContextSource.class);
        ldapContextSource.setReferral("follow");
        ldapContextSource.afterPropertiesSet();
    }


现在认证需要很长的时间,至少60秒。日志是这样说的:

2023-11-25T23:10:11.600+01:00 DEBUG 27484 : Failed to bind with any user DNs [[email protected]]
2023-11-25T23:10:11.600+01:00 TRACE 27484 : Searching for user using FilterBasedLdapUserSearch [searchFilter=(userPrincipalName={0}); searchBase=; scope=subtree; searchTimeLimit=0; derefLinkFlag=false ]
2023-11-25T23:10:11.600+01:00 TRACE 27484 : Searching for user '[email protected]', with FilterBasedLdapUserSearch [searchFilter=(userPrincipalName={0}); searchBase=; scope=subtree; searchTimeLimit=0; derefLinkFlag=false ]
2023-11-25T23:10:11.640+01:00 TRACE 27484 : Searching for entry under DN 'dc=xxx,dc=internal', base = '', filter = '(userPrincipalName={0})'
2023-11-25T23:10:11.647+01:00 DEBUG 27484 : Found DN: CN=Eriksson\, Viktor - e-bolvier,OU=External Users,OU=xxx,OU=Sweden,OU=Newxxx
2023-11-25T23:10:33.146+01:00 DEBUG 27484 : Found user '[email protected]', with FilterBasedLdapUserSearch [searchFilter=(userPrincipalName={0}); searchBase=; scope=subtree; searchTimeLimit=0; derefLinkFlag=false ]
2023-11-25T23:10:33.146+01:00 TRACE 27484 : Attempting to bind as cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal
2023-11-25T23:10:33.183+01:00 DEBUG 27484 : Bound cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal
2023-11-25T23:10:33.184+01:00 TRACE 27484 : Searching for roles for user [email protected] with DN cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal and filter (member=cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal) in search base 
2023-11-25T23:10:33.185+01:00 TRACE 27484 : Using filter: (member=cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal)
2023-11-25T23:10:54.453+01:00 DEBUG 27484 : Found roles from search []
2023-11-25T23:10:54.454+01:00 DEBUG 27484 : Retrieved authorities for user cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal
2023-11-25T23:10:54.454+01:00 DEBUG 27484 : Mapping user details from context with DN cn=Eriksson\, Viktor - e-bolvier,ou=External Users,ou=xxx,ou=Sweden,ou=Newxxx,dc=xxx,dc=internal
2023-11-25T23:10:54.455+01:00 DEBUG 27484 : Authenticated user


但是,尽管花了很长时间,它似乎没有找到任何角色。
所以我的问题。
为什么LDAP客户端这么快,似乎得到了我想要的结果,但代码是suuuper慢,不返回任何东西?
为什么我的dn里有奇怪的字符?

esbemjvw

esbemjvw1#

不知道这个参数是什么,但当我改变它时,一切都开始工作了。
public int findDuplicate(true);
我还添加了setIgnorePartialResultException(true);
删除referendum =follow。
因此,现在它速度很快,并且正确Map角色。
我的代码:

@Bean
    LdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) {
        String groupSearchBase = "";
        DefaultLdapAuthoritiesPopulator authorities =
                new DefaultLdapAuthoritiesPopulator(contextSource, groupSearchBase);
        authorities.setGroupSearchFilter("(member={0})");
        authorities.setSearchSubtree(true);
        authorities.setIgnorePartialResultException(true);

        return authorities;
    }

字符串

相关问题