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

Java 我可以从LDAP更改自己的Active Directory密码吗(无管理帐户),java,active-directory,ldap,spring-ldap,Java,Active Directory,Ldap,Spring Ldap,我没有(也不会)管理员帐户。 我想从java更改Active Directory中的我自己(用户)密码。 我该怎么做 使用来自web的代码: private void changePass() throws Exception { String oldpass = this.encodePassword("oldpass!"); String newpass = this.encodePassword("newpass!"); Attribute oldattr = ne

我没有(也不会)管理员帐户。 我想从java更改Active Directory中的我自己(用户)密码。 我该怎么做

使用来自web的代码:

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 });
}
这是contextSource

<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>
如果我将userDn更改为“cn=smith”,我会得到:

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

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

更新/解决

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

对于未来的搜索者:

无对象-表示ACtive Directory找不到对象(my cn=Users,cn=Smith) 要找到用户目录的完全限定规范路径,您可以使用用户属性“DiscrimitedName”(在我最糟糕的情况下,它是“cn=John\,Smith”,ou=Contractors,ou=user Accounts,ou=Accounts)

然后我得到:

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

然后:

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

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(约束类型)如果旧密码错误

顺便说一句

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

  • 如果
    cn=smith,cn=Users
    不是条目的真正DN,则需要是

  • 您不需要删除/添加/替换所有内容:只要使用replace_属性即可;如果您使用的是管理帐户来更改密码

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


  • 是的,你可以,但是这有点棘手

    首先要更改密码,您必须通过LDAPS而不是LDAP进行连接。这是使用TLS或SSL(至少128位)连接。下面是一个如何使用进行连接的示例

    其次,必须以UTF-16LE编码字节数组的形式传递密码。但在编码之前,应将其括在双引号中。下面是一个示例:

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

    非常感谢,我修复了getContext().modifyAttributes(“cn=Users”、new ModificationItem[]{new ModificationItem(DirContext.REPLACE_属性)、new BasicAttribute(“unicodePwd”、encodePassword(“mamamakassa22!”).getBytes(“UTF-16LE”))和cn=Users,现在我得到了SvcErr:DSID-03190C6B,问题5003(不会执行),数据0。可能问题不在SSL连接中?@JohnSmith我相信WILL_not_PERFORM意味着它需要比目前更高的安全性。如果您有API,您还应该考虑使用扩展密码修改操作,而不仅仅是此属性更改。如果您在更改时使用非管理员用户进行身份验证密码属性,您确实需要删除/添加内容。在这种情况下,没有简单的替换属性。@Johanneke同意,我错了(b):请参见编辑。
    String pass = "\"" + "newpass" + "\"";
    byte[] password = pass.getBytes("UTF-16LE");
    // You will need to handle UnsupportedEncodingException here