Могу ли я изменить пароль Active Directory из LDAP (без учетной записи администратора) - PullRequest
4 голосов
/ 14 марта 2012

У меня нет (и не будет) учетной записи администратора. Я хочу изменить сам (пользовательский) пароль в Active Directory с Java. Как я могу это сделать?

Использование кода из Интернета:

private void changePass() throws Exception {
    String oldpass = this.encodePassword("oldpass!");
    String newpass = this.encodePassword("newpass!");
    Attribute oldattr = new BasicAttribute("unicodePwd", oldpass);
    Attribute newattr = new BasicAttribute("unicodePwd", newpass);
    ModificationItem olditem = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, oldattr);
    ModificationItem newitem = new ModificationItem(DirContext.ADD_ATTRIBUTE, newattr);
    ModificationItem repitem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, newattr);
    ModificationItem[] mods = new ModificationItem[2];
    mods[0] = olditem;
    mods[1] = newitem;
    // ldapTemplate.modifyAttributes("cn=administrator,cn=Users", mods);
    ldapTemplate.modifyAttributes("cn=smith,cn=Users", new ModificationItem[] { repitem });
}

вот контекстный источник

<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
    <property name="url" value="ldap://ldapserver:389"/>
    <property name="base" value="dc=company,dc=com"/>
    <property name="userDn" value="smith@company"/>
    <property name="password" value="oldpass"/>
</bean>

Я получил:

LDAP: error code 32 - 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of:
'CN=Users,DC=company,DC=com'

если я изменю userDn на "cn = smith", я получу:

LdapErr: DSID-0C0903A9, комментарий: ошибка AcceptSecurityContext

Может быть, моя проблема в том, что я не понимаю, как работает LDAP? Возможно ли это (изменить пароль пользователя с помощью учетной записи пользователя) или нет? И, если это возможно, могу ли я проверить, что учетная запись заблокирована / истекает с такими же привилегиями?

ОБНОВЛЕНИЕ / РАЗРЕШЕНИЕ

большое спасибо за вашу помощь. Мне это тоже очень помогло.

для будущих искателей:

NO_OBJECT - означает, что ACtive Directory не может найти объект (мой cn = Users, cn = Smith) Чтобы найти полностью определенный канонический путь к каталогу пользователя, вы можете использовать атрибут пользователя " Однозначное имя " (в моем, наихудшем случае это " cn = John \, Smith", ou = Contractors, ou = User Счета, OU = счета »)

тогда я получил:

WILL_NOT_PERFORM - это может означать разные типы вещей. В моем случае был неправильный тип объекта, но, возможно, другие случаи, как описано ниже - не SSL-соединение (, не ldaps: // ) и другие.

, то:

INSUFF_ACCESS_RIGHTS - пользователь (не администратор не имеет права на атрибут REPLACE-password), чтобы изменить пароль, он должен ввести старый пароль и новый пароль, а затем УДАЛИТЬ старый и ДОБАВИТЬ новый.

Attribute oldattr = new BasicAttribute("unicodePwd", oldQuotedPassword.getBytes("UTF-16LE"));
Attribute newattr = new BasicAttribute("unicodePwd", newQuotedPassword.getBytes("UTF-16LE"));
ModificationItem olditem = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, oldattr);
ModificationItem newitem = new ModificationItem(DirContext.ADD_ATTRIBUTE, newattr);
ldapTemplate.modifyAttributes("cn=John\\, Smith,ou=Contractors,ou=User Accounts,ou=Accounts", new ModificationItem[] { olditem, newitem });

проблема 1005 (CONSTRAINT_ATT_TYPE) - если старый пароль неправильный

1055 * КСТАТИ *

javax.naming.PartialResultException: необработанные ссылки на продолжение; оставшееся имя '/' - при поиске человека / пользователя в глобальном масштабе (например, в методе authenticate) ldapTemplate.setIgnorePartialResultException ( правда ); можно починить

Ответы [ 2 ]

4 голосов
/ 14 марта 2012

Да, вы можете, однако это несколько сложно.

Сначала, чтобы изменить пароль, вы должны подключиться через LDAPS, а не LDAP.То есть с TLS или SSL (не менее 128 бит) соединением.Вот пример того, как это можно сделать с JNDI .

Во-вторых, вы должны передать пароль в виде байтового массива в кодировке UTF-16LE.Но прежде чем кодировать его, вы должны заключить его в двойные кавычки.Итак, вот пример:

String pass = "\"" + "newpass" + "\"";
byte[] password = pass.getBytes("UTF-16LE");
// You will need to handle UnsupportedEncodingException here
1 голос
/ 14 марта 2012
  1. Если cn=smith,cn=Users не является реальным DN записи, оно должно быть.

  2. Вам не нужно все, что удалить / добавить/ заменить вещи: просто используйте REPLACE_ATTRIBUTE; если вы используете административную учетную запись для смены пароля.

    Вам это нужно, если вы обновляете пароль как вы сами, т.е. когда вы привязаны к той же учетной записи, которую вы обновляете.Причина в том, что вы должны предоставить старый пароль для удаления и новый для вставки, чтобы можно было обнаружить сбой совпадения для старого пароля.В качестве альтернативы вы можете использовать расширенную операцию изменения пароля, при которой вы снова вводите старый и новый пароль.

...