Принудительное изменение пароля при следующем входе в Active Directory с использованием Apache LDAP API

Мы используем Active Directory (AD), и когда пользователи добавляются, они получают набор паролей и флаг для принудительного применения. Пользователь должен изменить пароль при следующем входе в систему, что приводит к атрибуту AD pwdLastSet=0

У меня есть приложение Java, использующее Apache LDAP API для аутентификации, но когда я это делаю, я получаю код ошибки 49 INVALID_CREDENTIALS и никаких указаний на смену пароля.

Как я могу с помощью Apache LDAP API определить, что пользователь должен сначала изменить пароль?

Мой простой аутентификатор:

    public void authenticate(String uid, String password) {
    String status = "";
    try {
        LdapConnectionConfig config = new LdapConnectionConfig();
        config.setUseSsl(true);
        config.setLdapHost("activedirectory.domain.net");
        config.setLdapPort(636);
        config.setTrustManagers(new NoVerificationTrustManager());
        config.setName(_ldapMgmtUser);
        config.setCredentials(_ldapMgmtPassword);

        final DefaultPoolableLdapConnectionFactory factory = new DefaultPoolableLdapConnectionFactory(config);
        final LdapConnectionPool pool = new LdapConnectionPool(factory);
        pool.setTestOnBorrow(true);
        final LdapConnectionTemplate ldapConnectionTemplate = new LdapConnectionTemplate(pool);

        final PasswordWarning warning = ldapConnectionTemplate.authenticate(_rootDn, "(sAMAccountName=" + uid + ")",
                SearchScope.SUBTREE, password.toCharArray());

        status = "User credentials authenticated";
        if (warning != null) {
            status = status + " \n Warning!!" + warning.toString();
        }
        System.out.println(status);
    } catch (final PasswordException e) {
        System.err.println("############# PasswordException #############");
        status = e.toString();
        e.printStackTrace();
    } catch (Exception e) {
        System.err.println("############# Exception #############");
        e.printStackTrace();

    } finally {
    }
    return;
}

person 4integration    schedule 18.05.2021    source источник


Ответы (1)


Я заметил, что при использовании LdapConnectionTemplate и authenticate(...) (как указано выше) он не возвращает никаких полезных кодов ошибок в исключении и не возвращает PasswordWarning. Разве этот сценарий не должен возвращать PasswordWarning? https://nightlies.apache.org/directory/api/2.0.1/apidocs/org/apache/directory/ldap/client/template/PasswordWarning.html

Если я использую: LdapNetworkConnection и connection.bind(...), он возвращает LdapException с сообщением 80090308: LdapErr: DSID-0C090453, comment: AcceptSecurityContext error, data 773, v3839, где 773 - это то, что ожидается.

Похоже, что в LdapConnectionTemplate есть (несколько) ошибок.

Полный код:

    public void authenticateWithBind(String uid, String password) {
        String status = "";
        LdapConnection connection = null;
        try {
            LdapConnectionConfig config = new LdapConnectionConfig();
            config.setUseSsl(true);
            config.setLdapHost("activedirectory.domain.net");
            config.setLdapPort(636);
            config.setTrustManagers(new NoVerificationTrustManager());
            config.setName(_ldapMgmtUser);
            config.setCredentials(_ldapMgmtPassword);

            connection = new LdapNetworkConnection(config);
            connection.bind(_ldapMgmtUser, _ldapMgmtPassword);

            EntryCursor cursor = connection.search(_rootDn, "(sAMAccountName=" + uid + ")", SearchScope.SUBTREE, "*");
            
            while (cursor.next()) {
                Entry entry = cursor.get();
                System.out.println("DN: " + entry.getDn());
                System.out.println("Attribute: " + entry.get("pwdLastSet"));

                connection.bind(entry.getDn(), password);
                status = "User credentials authenticated";
                System.out.println(status);
            }
        } catch (LdapException e) {
            System.err.println("############# LdapException #############");
            e.printStackTrace();
            System.err.println("Error message: " + e.getMessage());

        } catch (Exception e) {
            System.err.println("############# Exception #############");
            e.printStackTrace();
            System.err.println("Error message: " + e.getMessage());
        } finally {
            closeConnection(connection);
        }
        return;
    }

person 4integration    schedule 19.05.2021
comment
Предупреждения возвращаются как элементы управления реакцией, а не как коды ошибок. - person user207421; 19.05.2021