繁体   English   中英

简单 Spring 引导 LDAP 身份验证示例不适用于 ActiveDirectory

[英]Simple Spring Boot LDAP authentication example does not work with ActiveDirectory

我找到了一个非常简单的 LDAP 身份验证示例,它使用嵌入式 LDAP 服务器工作得很好: https://github.com/asbnotebook/spring-boot/tree/master/spring-security-embedded-ldap-example 这正是我所需要的——添加了一个配置 class,现在所有用户都需要在访问该应用程序之前登录。

由于我们的 AD(本地服务器,不是 Azure AD)需要 userDN 和密码才能访问,我将其添加到示例代码中,还修改了 url、base dn 等。

当我尝试登录时,总是收到“凭据错误”错误消息。 然后我逐步查看代码,发现 Spring LDAP 代码成功地从 AD 中检索了一些用户数据(我在“userDetails”object 中找到了用户 email 地址,只有在 AD 中才知道),但是设置了“密码”字段到 null。然后将此 null 值与用户输入的密码进行比较,失败并在 function org.springframework.security.authentication.dao.additionalAuthenticationChecks() 中抛出 BadCredentialsException。

所以现在我有两个问题:

  1. 为什么“密码”属性设置为 null? 我的理解是它应该包含密码 hash。我用 ldapsearch 检查了 AD 响应,但我没有看到任何看起来像密码 hash 的东西。但是 userDN 确实可以与其他应用程序一起使用,所以它可能不是 userDN AD 的问题帐户。 请告知如何正确找回密码信息。

  2. 我相信该示例不处理密码哈希。 用于预加载示例应用程序的嵌入式 LDAP 服务器的 LDIF 文件只包含 userPassword 属性的明文密码。 此外,示例代码中的 passwordEncoder 看起来像一个无操作编码器。 我应该如何更改它以使其与 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();
    }
}

在考虑了Gabriel Luci 的评论之后,我现在找到了一种使用 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);
    }
}

可以使用 email 地址或 sAMAccountName 登录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM