2015-05-29 68 views
3

您好我正在尝试使用WebSecurityConfigurerAdapter类实现spring的ldap身份验证。如何正确使用configurer类来实现Spring Security Ldap身份验证?

到目前为止,我可以通过内存方法甚至是我的公司的LDAP服务器进行身份验证,但是后一种方法我只能通过硬编码的userDN和密码进行身份验证,如果我创建新的上下文“T创建新的上下文或者我不把用户DN和密码,JVM抛出我:

Caused by: 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\u0000]; Remaining name: '/' 

我的问题是,我怎么可以从登录表单的用户密码和用户DN这样我就可以把它在上下文中?如果这是不可能的我怎么能得到密码和userDn的上下文?

这是我的代码:

@Configuration 
@EnableWebMvcSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 

     auth.ldapAuthentication().userSearchFilter("(&(objectClass=user)(sAMAccountName={0}))") 
      .groupSearchFilter("(&(memberOf:1.2.840.113556.1.4.1941:=CN=DL - DC859 - MIDDLEWARE,OU=Dyn,OU=Dist,OU=Security Groups,OU=POP,DC=pop,DC=corp,DC=local))") 
      .contextSource(getLdapContextSource()); 
    } 

    private LdapContextSource getLdapContextSource() throws Exception { 
     LdapContextSource cs = new LdapContextSource(); 
     cs.setUrl("ldap://tcp-prd.pop.corp.local:389"); 
     cs.setBase("DC=pop,DC=corp,DC=local"); 
     cs.setUserDn("[email protected]"); 
     cs.setPassword("mypassword"); 
     cs.afterPropertiesSet(); 
     return cs; 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
      .antMatchers("/resources/**").permitAll() 
      .anyRequest().authenticated() 
      .and() 
      .formLogin() 
      .loginPage("/login") 
      .permitAll();  
    } 

} 

谢谢。

+0

使用LDAP认证有两种模式。首先你知道如何根据他的用户名构建用户的DN(它甚至可以是DN本身)。其次,您需要执行LDAP搜索来查找用户的DN。对于后者,您需要拥有技术登录,以便LDAP认证组件可以找到用户条目。这就是你应该用你的例子来判断。您应该要求您的LDAP管理员为您的应用程序创建技术帐户,并在您的'LdapContextSource'中使用它。 –

+0

我知道userDN将始终是用户放入用户名框+ @ pop.corp.local的内容。 我首先想到auth知道上下文并在里面有用户名,但这似乎不是真的,因此我必须创建一个新的上下文。我只是不知道如何从那里获得凭据。 –

+0

这不是DN,即域登录名。但是也许你可以用Active Directory登录。我不确定。 –

回答

2

我终于想通了this的帖子。我仍然不知道如何设置组过滤器,但至少现在我可以绑定到服务器。

@Bean 
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() { 
    ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("pop.corp.local", 
      "ldap://tcp-prd.pop.corp.local:389"); 
     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()); 
} 

    @Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .antMatchers("/resources/**").permitAll() 
      .anyRequest().authenticated() 
      .and() 
     .formLogin() 
      .loginPage("/login") 
      .permitAll();  
} 

编辑:我终于找到了如何按组过滤。事实证明,他们在ActiveDirectoryLdapAuthenticationProvider类v3.2.6中添加了一个setSearchFilter()方法。当我使用旧版本时,我从来不知道这一点。所以我用该方法创建了一个类的副本,并创建了一个buildFilter方法来创建传递给setSearchFilter的过滤器字符串。