Spring security springmvc中的Ldap认证

Spring security springmvc中的Ldap认证,spring-security,ldap,Spring Security,Ldap,我正在尝试为我的SpringMVC应用程序集成LDAP身份验证。如果我将contextSource设置为虚拟用户DN和相应的密码,则用户可以成功登录。 我想做的是能够绑定ldap连接而不使用虚拟用户 下面是工作原理的代码- @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void c

我正在尝试为我的SpringMVC应用程序集成LDAP身份验证。如果我将contextSource设置为虚拟用户DN和相应的密码,则用户可以成功登录。 我想做的是能够绑定ldap连接而不使用虚拟用户

下面是工作原理的代码-

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http

            .authorizeRequests()
                .antMatchers("/css/**").permitAll()
                .antMatchers("/","/login**").permitAll()
                .antMatchers("/home_vm","/details/**").authenticated() 
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .defaultSuccessUrl("/home_vm", true)
                .and()
            .logout()
                .permitAll();

        http.headers().httpStrictTransportSecurity();

    }

    @Configuration
    @Profile({"default", "opt_ad_auth"})
    protected static class ActiveDirectoryAuthenticationConfiguration extends
            GlobalAuthenticationConfigurerAdapter {
        @Value("${app.ldap.url}")
        private String ldapURL;
        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {


             DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapURL);

           contextSource.setUserDn("cn=Dummy User,cn=Users,dc=somecompany,dc=com");



              contextSource.setPassword("mypassword");

            contextSource.setReferral("follow"); 

            contextSource.afterPropertiesSet();



                auth.ldapAuthentication()

                .userSearchFilter("(sAMAccountName={0})")

                    .contextSource(contextSource)
                    ;

        }
    }   
}
现在我尝试删除硬编码的userDn和密码(更新了init())-

该应用程序启动良好,但我得到一个例外-“一个成功的绑定必须在连接上完成”

Stacktrace-

org.springframework.security.authentication.InternalAuthenticationServiceException: Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1
[更新]我已将init方法修改为以下内容,以便更密切地遵循spring教程()


我没有得到前面提到的绑定异常,但仍然无法进行身份验证。错误的凭据。

您可以通过两种形式使用LDAP进行身份验证:

您可以使用用户的完整DN(LDAP树中的完整路径)和密码进行绑定

或者,您可以作为超级用户绑定到LDAP,超级用户可以搜索所有LDAP树。LDAP验证器查找用户DN,并将用户密码与用户条目中的密码进行比较

在第一个代码中使用第二个系统。您需要一个可以在LDAP上绑定并找到用户条目的用户


如果希望用户访问第二个系统,则必须提供用户条目的完整DN,而不仅仅是uid。

您需要分两步执行此操作:

  • 以管理用户的身份绑定到LDAP,该用户有足够的权限搜索树,并通过您拥有的有关该用户的任何唯一信息找到该用户
  • 使用提供的密码重新绑定到LDAP,作为找到的用户的DN
  • 断开

  • 如果所有操作都成功,则用户名存在且密码正确。如果出现任何故障,应将其视为登录故障。具体来说,您不应该告诉用户是找不到用户名还是密码不正确是导致失败的原因:这是对附件的信息泄漏。

    您不应该自己获取和比较密码,除非LDAP服务器配置错误,否则您不能,因为它是内部散列的。您应该通过重新绑定提供密码,并让LDAP进行比较。谢谢您的评论。我知道首先需要一个约束。我试图做的是-使用用户在登录屏幕上输入的凭据,并将其用于绑定和身份验证。你是说这是不可能的,我需要使用一个单独的用户进行绑定吗?
    org.springframework.security.authentication.InternalAuthenticationServiceException: Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1
    
    public void init(AuthenticationManagerBuilder auth) throws Exception {
    
            auth.ldapAuthentication()
            .userDnPatterns("sAMAccountName={0}")
            .contextSource().url(ldapURL)
                ;
    
    }