用于Spring LDAP身份验证的登录名

Nas*_*din 1 ldap spring-security spring-boot

我创建了一个本地LDAP服务器,并添加了密码为"123456"的用户"djiao" 在此输入图像描述

尝试使用Spring Boot实现Spring Security的身份验证.我的webconfig类如下:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
            .formLogin();
    }

    @Bean
    public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("", "ldap://localhost:10389");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
    }

    @Bean
    public LoggerListener loggerListener() {
        return new LoggerListener();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
    }
Run Code Online (Sandbox Code Playgroud)

但是我似乎无法从登录页面登录.

  1. 如果我使用djiao(cn)或djiao1(uid),我会得到500.

    [LDAP:错误代码34 - 给出错误的DN:djiao1(0x64 0x6A 0x69 0x61 0x6F 0x31)无效]; 嵌套异常是javax.naming.InvalidNameException:[LDAP:错误代码34 - 给出不正确的DN:djiao1(0x64 0x6A 0x69 0x61 0x6F 0x31)无效]

  2. 如果我使用dn"cn = djiao,ou = Users,dc = example,dc = com"作为用户名,我将收到"Bad credentials"错误.密码只是123456.

登录用户名应该是什么?或者我在websecurityconfig类中遗漏了什么?

dan*_*ten 6

从您的代码中我可以确定您正在使用Spring-Boot.

这是我们连接到LDAP的工作原理

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder authBuilder) throws Exception {
        authBuilder
            .ldapAuthentication()
            .userSearchFilter("(sAMAccountName={0})")
            .userSearchBase("dc=some,dc=domain,dc=com")
            .groupSearchBase("ou=groups,dc=some,dc=domain,dc=com")
            .groupSearchFilter("member={0}")
            .contextSource()
                .url("ldaps://<ldap-server>")
                .port(639)
                .managerDn("cn=binduser,ou=users,dc=some,dc=domain,dc=com")
                .managerPassword("some pass")
        ;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以从本质上说,userSearchFilter你必须定义不同的价值观.如果您使用除AD以外的任何LDAP,您的过滤器应该由"(uid={0})"或者如果您不想让人们使用您也可以使用的电子邮件,"(mail={0})"或者您可以使用这样的组合"(|(uid={0})(mail={0}))",那么woul允许同时使用这两者.

如果你去ActiveDirectory - 我认为你没有基于你上面写的内容 - 它应该是sAMAccountName如上所述,允许人们只在域中输入他们的ID,就像MYDOMAIN\myusername登录一样myusername.

如果您需要连接到多个LDAP服务器,这些LDAP服务器为HA目的共享相同的信息,您可以通过.contextSource().url()呼叫执行此操作.如果它们带有不同的,例如'EMEA','US','AP',您可以使用以下方法组合这些呼叫:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder authBuilder) throws Exception {
    authBuilder
        .ldapAuthentication()
        .userSearchFilter("(sAMAccountName={0})")
        .userSearchBase("dc=emea,dc=domain,dc=com")
        .groupSearchBase("ou=groups,dc=emea,dc=domain,dc=com")
        .groupSearchFilter("member={0}")
        .contextSource()
            .url("ldaps://<emea-ldap-server>")
            .port(639)
            .managerDn("cn=binduser,ou=users,dc=emea,dc=domain,dc=com")
            .managerPassword("some pass")
        .and()
        .and()
        .ldapAuthentication()
        .userSearchFilter("(sAMAccountName={0})")
        .userSearchBase("dc=ap,dc=domain,dc=com")
        .groupSearchBase("ou=groups,dc=ap,dc=domain,dc=com")
        .groupSearchFilter("member={0}")
        .contextSource()
            .url("ldaps://<ap-ldap-server>")
            .port(639)
            .managerDn("cn=binduser,ou=users,dc=ap,dc=domain,dc=com")
            .managerPassword("some pass")

    ;
}
Run Code Online (Sandbox Code Playgroud)

BTW:这也允许您将不同的身份验证机制(如InMemory(Default-Admin-Backdoor))与LDAP和/或JDBC结合使用.