Spring 引导 ldap 安全

Spring boot ldap security

您好,我在使用 Ldap 创建简单登录时遇到问题。我已经从 spring.io 网站下载了入门项目:Getting started LDAP.

它与 ldif 文件完美配合,但我想用 运行 ldap 服务器替换它。我已经试了好几天了,没有任何进展。我用这段代码得到了最好的结果(替换在入门项目的 WebSecurityConfig 中)

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }
 
    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.authenticationProvider(activeDirectoryLdapAuthenticationProvider()).userDetailsService(userDetailsService());
    }
 
    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(null, "ldap://ip:port/", "ou=GROUP,dc=domain,dc=com");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
 
        return provider;
    }
}

如果我尝试使用格式为“用户名”“密码”的正确用户名和密码登录,控制台输出:ActiveDirectoryLdapAuthenticationProvider:Active Directory 身份验证失败:提供的密码无效

如果我使用“用户名@domain.com”和正确的密码,页面只会重新加载,不会向控制台输出任何内容。

如果我使用随机用户名和密码控制台:Active Directory 身份验证失败:提供的密码无效

有人可以帮忙吗?

按照评论中的建议,我打开了日志记录,发现问题也与“用户名@domain.com”相同。

问题出在 aciveDirectoryLdapAuthenticationProvider() 里面有 3 个问题。

  1. 我已经从 rootDn 中删除了 OU 组并添加了域,因此我们只能使用用户名登录。
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://ip:port/", "dc=domain,dc=com");
  1. 更改了提供商的搜索过滤器
provider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
  1. 最后我不得不更改 ActiveDirectoryLdapAuthProvider searchForUser 方法,因为它匹配“用户名@domain.com”与 sAMAccountName 而不是“用户名”。这个:
return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context,
                    searchControls, searchRoot, searchFilter,
                    new Object[] { bindPrincipal });    

替换为:

return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context,
                searchControls, searchRoot, searchFilter,
                new Object[] { username }); 

完成 aciveDirectoryLdapAuthenticationProvider:

    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://ip:port/", "dc=domain,dc=com");  
        provider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
    }

有人可以为 second/third 问题提供更好的解决方案吗?也许更好的搜索过滤器?我在 ldap 中没有任何字段匹配使用 ActiveDirectoryLdapAuthProvider.

的 bindPrincipal 的“username@domain.com”格式