我正在尝试使用 Spring LDAP 和 Spring security 进行身份验证,然后查询我们的公司 LDAP。我设法使身份验证工作,但是当我尝试运行搜索时,我总是得到以下异常

In order to perform this operation a successful bind must be completed on the connection



经过大量研究,我有一个理论,即在我进行身份验证之后,在我可以查询之前,我需要绑定(bind)到连接。我只是不知道什么和如何?

顺便提一下 - 我可以使用 JXplorer 成功浏览和搜索我们的 LDAP,所以我的参数是正确的。

这是我的 securityContext.xml 的一部分
<security:http auto-config='true'> 
    <security:intercept-url pattern="/reports/goodbye.html"  
            access="ROLE_LOGOUT" /> 
    <security:intercept-url pattern="/reports/**" access="ROLE_USER" /> 
    <security:http-basic /> 
    <security:logout logout-url="/reports/logout"  
            logout-success-url="/reports/goodbye.html" /> 
</security:http> 
<security:ldap-server url="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" /> 
<security:authentication-manager> 
    <security:authentication-provider ref="ldapAuthProvider"> 
</security:authentication-provider> 
</security:authentication-manager> 
<!-- Security beans --> 
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"> 
    <constructor-arg value="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" /> 
</bean> 
<bean id="ldapAuthProvider"  
   class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider"> 
    <constructor-arg> 
        <bean class="foo.bar.reporting.server.security.ldap.LdapAuthenticatorImpl"> 
            <property name="contextFactory" ref="contextSource" /> 
            <property name="principalPrefix" value="TD\" /> 
            <property name="employee" ref="employee"></property> 
        </bean> 
    </constructor-arg> 
    <constructor-arg> 
      <bean class="foo.bar.reporting.server.security.ldap.LdapAuthoritiesPopulator" /> 
    </constructor-arg> 
</bean> 
<!-- DAOs --> 
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"> 
  <constructor-arg ref="contextSource" /> 





这是来自 LdapAuthenticatorImpl 的代码片段执行身份验证。这里没问题:
@Override 
public DirContextOperations authenticate(final Authentication authentication) { 
    // Grab the username and password out of the authentication object. 
    final String name = authentication.getName(); 
    final String principal = this.principalPrefix + name; 
    String password = ""; 
    if (authentication.getCredentials() != null) { 
        password = authentication.getCredentials().toString(); 
    } 
    if (!("".equals(principal.trim())) && !("".equals(password.trim()))) { 
        final InitialLdapContext ldapContext = (InitialLdapContext) 
     this.contextFactory.getContext(principal, password); 
        // We need to pass the context back out, so that the auth provider  
        // can add it to the Authentication object. 
        final DirContextOperations authAdapter = new DirContextAdapter(); 
        authAdapter.addAttributeValue("ldapContext", ldapContext); 
        this.employee.setqId(name); 
        return authAdapter; 
    } else { 
        throw new BadCredentialsException("Blank username and/or password!"); 
    } 
} 

这是来自 EmployeeDao 的另一个代码片段我徒劳地尝试查询:
public List<Employee> queryEmployeesByName(String query)  
   throws BARServerException { 
    AndFilter filter = new AndFilter(); 
    filter.and(new EqualsFilter("objectclass", "person")); 
    filter.and(new WhitespaceWildcardsFilter("cn", query)); 
    try { 
        // the following line throws bind exception 
        List result = ldapTemplate.search(BASE, filter.encode(),  
            new AttributesMapper() { 
            @Override 
            public Employee mapFromAttributes(Attributes attrs)  
                throws NamingException { 
                Employee emp = new Employee((String) attrs.get("cn").get(),  
                   (String) attrs.get("cn").get(), 
                        (String) attrs.get("cn").get()); 
                return emp; 
            } 
        }); 
        return result; 
    } catch (Exception e) {  
        throw new BarServerException("Failed to query LDAP", e); 
    } 
} 

最后 - 我得到的异常(exception)
org.springframework.ldap.UncategorizedLdapException:  
    Uncategorized exception occured during LDAP processing; nested exception is  
    javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr:  
    DSID-0C090627, comment: In order to perform this operation a successful bind  
    must be completed on the connection., data 0, vece]; remaining name  
    'DC=TD,DC=FOO,DC=COM' 

请您参考如下方法:

看起来您的 LDAP 配置为不允许在未绑定(bind)的情况下进行搜索(无匿名绑定(bind))。你也实现了PasswordComparisonAuthenticator而不是 BindAuthenticatorauthenticate到 LDAP。

您可以尝试修改您的queryEmployeesByName()方法绑定(bind)然后搜索,查看doc中的一些示例.


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!