Spring LDAP — привязка для успешного подключения

Я пытаюсь аутентифицироваться, а затем запрашиваю наш корпоративный LDAP, используя Spring LDAP и безопасность Spring. Мне удалось заставить аутентификацию работать, но когда я пытаюсь запустить поиск, я всегда получаю следующее исключение

Для выполнения этой операции необходимо выполнить успешную привязку соединения.

После долгих исследований у меня появилась теория, что после аутентификации и до того, как я смогу запросить, мне нужно привязаться к соединению. Я просто не знаю, что и как?

Просто хочу отметить, что я могу успешно просматривать и искать наш LDAP с помощью JXplorer, поэтому мои параметры верны.

Вот раздел моего 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'

person Bostone    schedule 10.03.2011    source источник
comment
Я знаю, что это старо, но @Bostone, не могли бы вы помочь мне разобраться с этим. Я получаю точно такое же исключение, однако я получаю эту ошибку на странице входа, где пользователь сначала вводит учетные данные. ldap успешно возвращается, когда введено правильное имя пользователя и пароль, но я получаю следующую ошибку: [LDAP: код ошибки 1 - 00000000: LdapErr: DSID-0C090627, комментарий: для выполнения этой операции необходимо выполнить успешную привязку соединения. , данные 0, vece ]; оставшееся имя ''   -  person user1647708    schedule 25.03.2014
comment
@ user1647708, пожалуйста, смотрите мой ответ ниже. Это сработало для меня   -  person Bostone    schedule 26.03.2014


Ответы (3)


Похоже, ваш LDAP настроен на запрет поиска без привязки к нему (без анонимной привязки). Также вы внедрили PasswordComparisonAuthenticator, а не BindAuthenticator для аутентификации в LDAP.

Вы можете попробовать изменить свой метод queryEmployeesByName() для привязки, а затем выполнить поиск, посмотрев несколько примеров в документ.

person Raghuram    schedule 10.03.2011
comment
Это читается как комментарий, что вы предлагаете? Я знаю, что это возможно, так как я могу использовать JXplorer (это java-приложение) для подключения и поиска LDAP. Я просто не могу понять, как связать. Я думаю, что пробовал BindAuthenticator в прошлом и получил такое же исключение - person Bostone; 10.03.2011
comment
@Droidln.net. Отредактировал ответ с явным предложением. - person Raghuram; 10.03.2011
comment
Это очень документ, который я использовал для аутентификации кода. Когда они говорят о привязке/отвязке, они имеют в виду вставку/удаление записей в этом конкретном примере. - person Bostone; 10.03.2011

Я собираюсь принять ответ @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 начал работать.

person Bostone    schedule 11.03.2011
comment
Вы установили значения для userDn и password на реальные значения? Я имею в виду, что если я это сделаю, все увидят это в виде обычного текста. Как я могу прочитать его, например, из формы входа? - person Arthur Eirich; 11.05.2017

У меня такая же ошибка, не могу найти решение. Наконец, я изменил идентификатор пула приложений на сетевую службу, и все заработало как часы. (На моем сайте включена проверка подлинности Windows и анонимность)

person Alex Z    schedule 09.01.2013