【问题标题】:Spring LDAP - bind for successful connectionSpring LDAP - 绑定成功连接
【发布时间】:2011-07-12 10:15:14
【问题描述】:

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

为了执行此操作,必须在连接上完成成功的绑定

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

顺便提一下 - 我可以使用 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 的代码sn-p,它执行身份验证。这里没问题:

@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的另一个代码sn-p,我徒劳地尝试查询:

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'

【问题讨论】:

  • 我知道这是旧的,但@Bostone 你能帮我解决这个问题吗?我得到完全相同的异常,但是我在用户首次输入凭据的登录页面上收到此错误。输入正确的用户名和密码后,ldap 成功返回,但出现以下错误:[LDAP:错误代码 1 - 00000000:LdapErr:DSID-0C090627,注释:为了执行此操作,必须在连接上成功绑定。 , 数据 0, vece ];改名''
  • @user1647708 请在下面查看我的回答。它对我有用

标签: spring-security ldap bind spring-ldap


【解决方案1】:

您的 LDAP 似乎已配置为不允许在未绑定的情况下进行搜索(无匿名绑定)。您还实现了PasswordComparisonAuthenticator 而不是BindAuthenticatorauthenticate 到LDAP。

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

【讨论】:

  • 这看起来像是一条评论,你有什么建议?我知道这是可能的,因为我可以使用 JXplorer(它是 java 应用程序)来连接和搜索 LDAP,我只是不知道如何绑定。我想我过去尝试过 BindAuthenticator 并以同样的异常结束
  • @Droidln.net。用明确的建议编辑了答案。
  • 这是我用来编码身份验证的非常文档。当他们谈论绑定/解除绑定时,他们的意思是在该特定示例中插入/删除记录
【解决方案2】:

我将接受@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 搜索开始工作

【讨论】:

  • 您是否将userDnpassword 的值设置为实际值?我的意思是,如果我这样做,每个人都会以纯文本形式看到它。例如,如何从登录表单中读取它?
【解决方案3】:

我遇到了同样的错误,找不到解决方案。 最后,我将应用程序池标识更改为网络服务,一切都像魅力一样工作。 (我在我的网站上启用了 Windows 身份验证和匿名)

【讨论】:

    猜你喜欢
    • 2021-11-10
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    相关资源
    最近更新 更多