spring-security 简单的Sping Boot LDAP身份验证示例不适用于ActiveDirectory

k4emjkb1  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(138)

我找到了一个非常简单的LDAP身份验证示例,它使用嵌入式LDAP服务器就能很好地工作:https://github.com/asbnotebook/spring-boot/tree/master/spring-security-embedded-ldap-example。这正是我所需要的-添加了一个config类,现在所有用户都需要在访问应用程序之前登录。
由于我们的AD(本地服务器,而不是Azure AD)需要用户DN和密码才能访问,因此我将其添加到示例代码中,还修改了url、基本DN等。
当我尝试登录时,总是收到“Bad credentials”错误消息。(我在“userDetails”对象中找到了用户电子邮件地址,该对象仅在AD中已知),然而“password”字段被设置为空。然后将该空值与用户输入的密码进行比较,这失败了,并且在函数org. springframework中抛出BadCredentialsException。安全性。身份验证。dao.additionalAuthenticationChecks()。
所以现在我有两个问题:
1.为什么将“password”属性设置为空?我的理解是它应该包含密码哈希。我使用ldapsearch检查了AD响应,但没有看到任何类似密码哈希的内容。但是,userDN确实可以与其他应用程序一起使用,因此可能不是userDN AD帐户的问题。请建议如何正确检索密码信息。
1.我相信这个例子并不处理密码哈希值。用于预加载示例应用程序的嵌入式LDAP服务器的LDIF文件只包含userPassword属性的明文密码。另外,示例代码中的passwordEncoder看起来像是一个No Op Encoder。我应该如何更改它以使其与AD一起工作?
下面是我的代码:

package com.asbnotebook.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.userdetails.LdapUserDetailsManager;

@Configuration
public class LdapSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public UserDetailsService userDetailsService() {

        var cs = new DefaultSpringSecurityContextSource("ldaps://ad.company.local/dc=company,dc=local");
        cs.setUserDn("cn=robot1,ou=robots");
        cs.setPassword("secret");
        cs.afterPropertiesSet();

        var manager = new LdapUserDetailsManager(cs);
        manager.setUsernameMapper(new DefaultLdapUsernameToDnMapper("ou=company_user", "cn"));
        manager.setGroupSearchBase("ou=company_groups");

        return manager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}
vom3gejh

vom3gejh1#

在考虑了Gabriel Luci's注解之后,我现在找到了一种简单的方法来使用ActiveDirectory进行身份验证:

package com.asbnotebook.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;

@Configuration
public class LdapSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        ActiveDirectoryLdapAuthenticationProvider adProvider =
                new ActiveDirectoryLdapAuthenticationProvider(
                        "company.de","ldaps://ad.company.local","dc=company,dc=local");
        adProvider.setConvertSubErrorCodesToExceptions(true);
        adProvider.setUseAuthenticationRequestCredentials(true);
        auth.authenticationProvider(adProvider);
        auth.eraseCredentials(false);
    }
}

可以使用电子邮件地址或sAMAccountName登录。

相关问题