2011-03-10 92 views
7

我试图验证,然后使用Spring LDAP和Spring安全性查询我们的公司LDAP。我设法使认证工作,但是当我尝试运行搜索我总是得到以下异常春季LDAP - 绑定成功连接

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

大量的研究后,我有一个理论,之前之后我验证和我可以查询我需要绑定连接。我只是不知道什么和如何?

只要提一下 - 我可以使用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); 
    } 
} 

最后一点 - 我越来越

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' 
+0

我知道这是旧的,但@Bostone你能帮我解决这个问题。我得到完全相同的异常,但是我在用户首次输入凭据的登录页面上收到此错误。当输入正确的用户名和密码时,ldap会成功返回,但出现以下错误:[LDAP:错误代码1- 00000000:LdapErr:DSID-0C090627,注释:为了执行此操作,必须在连接上完成成功绑定。 ,数据0,vece];重新命名“' – user1647708 2014-03-25 16:48:39

+0

@ user1647708请参阅下面的答案。它为我工作 – Bostone 2014-03-26 17:29:53

回答

4

它看起来异常就像你的LDAP被配置为不允许搜索而不绑定它(没有匿名绑定)。您还实施了PasswordComparisonAuthenticator而不是BindAuthenticatorauthenticate到LDAP。

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

+0

这听起来像一个评论,你有什么建议?我知道这是可能的,因为我可以使用JXplorer(这是Java应用程序)来连接和搜索LDAP我只是无法弄清楚如何绑定。我想我过去曾尝试过BindAuthenticator,并且以相同的例外 – Bostone 2011-03-10 05:09:42

+0

@ Droidln.net结束。用明确的建议编辑答案。 – Raghuram 2011-03-10 10:06:17

+0

这是我用来编码验证的非常文档。当他们在说绑定/解除绑定时,他们的意思是插入/删除特定示例中的记录 – Bostone 2011-03-10 18:13:02

3

我打算接受@Raghuram答案,主要是因为它让我思考着正确的方向。

为什么我的代码失败了?原来 - 我接线的方式我试图进行匿名搜索,这是系统禁止的 - 因此错误。

如何重新连接上面的示例工作?第一件事(也就是丑陋的事情),你需要提供用户名和用于访问系统的用户密码。甚至在您登录和认证时也是非常不直观的,即使您正在使用BindAuthenticator系统也不会尝试重用您的凭证。游民。所以,你需要坚持2个参数为contextSource定义,像这样:

<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"> 
    <constructor-arg value="ldap://foo.com:389/dc=td,dc=foo,dc=com" /> 
    <!-- TODO - need to hide this or encrypt a password --> 
    <property name="userDn" value="CN=admin,OU=Application,DC=TD,DC=FOO,DC=COM" /> 
    <property name="password" value="blah" /> 
</bean> 

这样做,让我与通用BindAuthenticator,然后我的Java搜索开始着手

+1

您是否已将“userDn”和“password”的值设置为实际值?我的意思是,如果我这样做,每个人都会以纯文本的方式看到它。我怎样才能从登录表单读取它? – 2017-05-11 14:08:05

0

我得到了同样的错误取代认证的自定义实现,找不到解决方案。 最后,我将应用程序池标识更改为网络服务,并且所有操作都像魅力一样。 (我有Windows身份验证和匿名在我的网站上启用)