我可以从 LDAP 更改自己的 Active Directory 密码(无需管理帐户)

xte*_*ern 6 java ldap active-directory spring-ldap

我没有(也不会)拥有管理员帐户。我想从 java 更改 Active Directory 中自己(用户)的密码。我怎样才能做到这一点?

使用来自网络的代码:

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 });
}
Run Code Online (Sandbox Code Playgroud)

这是上下文源

<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>
Run Code Online (Sandbox Code Playgroud)

我有:

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

如果我将 userDn 更改为“cn=smith”,我得到:

LdapErr:DSID-0C0903A9,注释:AcceptSecurityContext 错误

也许我的问题是我不明白 LDAP 是如何工作的?是否可以(使用用户帐户更改用户密码)?而且,如果可能的话,我可以检查帐户锁定/过期是否具有相同的权限吗?

更新/解决

非常感谢您的帮助。这对我也很有帮助。

对于未来的搜索者:

NO_OBJECT - 意味着 Active Directory 无法找到对象(我的 cn=Users,cn=Smith) 要查找用户目录的完全限定规范路径,您可以使用用户属性“ distinguishedName ”(在我最坏的情况下,它是“ cn=John\, Smith",ou=承包商,ou=用户帐户,ou=帐户" )

然后我得到:

WILL_NOT_PERFORM - 这可能意味着不同类型的事情。就我而言,存在错误的对象类型,但是,可能存在其他情况,如下所述 - 不是 SSL 连接(不是 ldaps://),以及其他情况。

然后:

INSUFF_ACCESS_RIGHTS - 用户(非管理员无权替换密码属性),要更改密码,他必须输入旧密码和新密码,然后删除旧密码并添加新密码。

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 });
Run Code Online (Sandbox Code Playgroud)

问题 1005 (CONSTRAINT_ATT_TYPE) - 如果旧密码错误

顺便提一句

javax.naming.PartialResultException:未处理的延续引用;剩余名称 '/' - 在全局搜索人员/用户时(例如,在认证方法中) ldapTemplate.setIgnorePartialResultException( true ); 可以修复它

Sha*_*Fel 5

是的,您可以,但是有点棘手。

首先要更改密码,您必须通过 LDAPS 而不是 LDAP 连接。即使用 TLS 或 SSL(至少 128 位)连接。下面是如何使用JNDI完成此操作的示例。

其次,您必须将密码作为 UTF-16LE 编码的字节数组传递。但在对其进行编码之前,应该将其用双引号引起来。这是一个例子:

String pass = "\"" + "newpass" + "\"";
byte[] password = pass.getBytes("UTF-16LE");
// You will need to handle UnsupportedEncodingException here
Run Code Online (Sandbox Code Playgroud)


use*_*421 2

  1. 如果cn=smith,cn=Users不是条目的真实 DN,则必须是。

  2. 您不需要所有删除/添加/替换的内容:只需使用 REPLACE_ATTRIBUTE;如果您使用管理帐户来更改密码。

    如果您要以自己的身份更新密码,即绑定到您要更新的同一帐户,则确实需要它。原因是您必须提供用于删除的旧密码和用于插入的新密码,以便可以检测到旧密码的匹配失败。或者,您可以使用扩展密码修改操作,其中您再次提供旧密码和新密码。