我不(也不会)拥有管理员帐户。 我想从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 });
}
这是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>
我得到了:
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) 要查找用户目录的完全合格的规范路径,您可以使用用户属性“ distinguishedName ”(在我的最坏情况下,它是“ cn = John \,Smith”,ou =承包商,ou =用户帐户,ou =帐户“)
然后我得到了:WILL_NOT_PERFORM - 这可能意味着不同类型的事情。在我的情况下,有错误的对象类型,但是,可能的其他情况,如下所述 - 不是SSL连接(不是ldaps:// ),还有其他情况。
然后:
INSUFF_ACCESS_RIGHTS - 用户(不是管理员无权使用REPLACE-password属性),要更改密码,必须输入旧密码和新密码,然后REMOVE old和ADD new。
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) - 如果旧密码错误
顺便说一句
javax.naming.PartialResultException:未处理的Continuation Reference(s); 剩余名称'/' - 搜索人/用户全局时(例如,在authenticate-method中) ldapTemplate.setIgnorePartialResultException(的真);可以解决它
答案 0 :(得分:4)
是的,你可以,但这有点棘手。
首先要更改必须通过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 :(得分:1)
如果cn=smith,cn=Users
不是条目的真实DN,则必须是。
您不需要删除/添加/替换所有东西:只需使用REPLACE_ATTRIBUTE; if 您正在使用管理帐户更改密码。
如果您要自己更新密码,即绑定到您正在更新的同一帐户时,您确实需要它。原因是您必须提供旧密码以进行删除,并使用新密码进行插入,以便可以检测旧密码的匹配失败。或者,您可以使用扩展密码修改操作,再次提供旧密码和新密码。