Spring Boot LDAP 安全性

3

你好,我有一个问题,想要使用LDAP创建简单的登录。我从spring.io网站下载了入门项目:Getting started LDAP

使用ldif文件时它可以完美地工作,但我想用运行中的LDAP服务器替换它。我已经尝试了几天,但没有进展。我在getting started项目的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身份验证失败:提供的密码无效。

如果我使用“username@domain.com”和正确的密码,则页面只会重新加载,没有任何输出到控制台。

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

有人能帮忙吗?


由于您在ActiveDirectoryLdapAuthenticationProvider的构造函数中使用了“null”作为域,因此您必须使用“userPrincipalName”(username@domain.com)进行身份验证。您可以打开日志记录以查找原因,或者如果您不使用LDAPS或StartTLS扩展操作,则可以使用网络跟踪确切地确定LDAP BIND请求是否成功。 - Bernhard Thalmayr
1个回答

2

如评论中建议的那样,我已经开启了日志并发现问题在于 "username@domain.com" 也是一样的。

问题出在 aciveDirectoryLdapAuthenticationProvider() 中,其中有三个问题。

  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方法,因为它将“username@domain.com”与sAMAccountName匹配,而不是“username”。这样做:
return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context,
                    searchControls, searchRoot, searchFilter,
                    new Object[] { bindPrincipal });    

replaced with this:

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;
    }

有人能够为第二/第三个问题提供更好的解决方案吗?或者使用更好的搜索过滤器?我在LDAP中没有任何与"username@domain.com"格式匹配的字段,这是使用ActiveDirectoryLdapAuthProvider的bindPrincipal。

嗨@user3551808,你能告诉我你是在哪里和如何打开日志记录的吗?我遇到了类似的错误,希望能看到更多的日志记录,但好像没有产生任何效果。我使用logback.xml,并在logback.xml的开头添加了“debug = true”的条目,但似乎并没有起到作用。 - soMuchToLearnAndShare
启用日志记录 logging.level.org.springframework.security: DEBUG - cmptrwizard
我使用了 https://www.broadleafcommerce.com/docs/core/5.2/tutorials/admin-customization-tutorials/using-ldap-admin-security 来制作自定义的ldapAuthenticatorProvider,它已经生效了。 - Sylhare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接