9

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認証を実行するコード スニペットを次に示します。ここでは問題ありません:

@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'
4

3 に答える 3

4

お使いの LDAP は、バインドせずに検索できないように構成されているようです (匿名バインドなし)。また、LDAPへの認証PasswordComparisonAuthenticatorを行わないように実装しています。BindAuthenticator

docqueryEmployeesByName()のいくつかの例を見て、バインドしてから検索するようにメソッドを変更してみてください。

于 2011-03-10T04:28:05.430 に答える
3

主に正しい方向に考えさせられたので、@Raghuramの回答を受け入れます。

コードが失敗したのはなぜですか? 結局のところ、私が配線した方法では、システムで禁止されている匿名検索を実行しようとしていたため、エラーが発生しました。

上記の例を再配線して動作させる方法は? 最初に (そして醜いことですが)、システムへのアクセスに使用するユーザーのユーザー名とパスワードを提供する必要があります。システムを使用している場合でも、ログインして認証した場合でも、非常に直感に反しBindAuthenticator、資格情報を再利用しようとしません。残念。contextSourceしたがって、次のように 2 つのパラメーターを定義に貼り付ける必要があります。

   <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検索が機能し始めました

于 2011-03-11T03:53:58.293 に答える
0

同じエラーが発生しましたが、解決策が見つかりませんでした。最後に、アプリケーション プール ID をネットワーク サービスに変更すると、すべてがうまく機能しました。(私のサイトでは Windows 認証と匿名が有効になっています)

于 2013-01-09T17:09:11.133 に答える