我正在尝试更改活动目录中用户的密码。首先,我尝试了独立的java应用程序,我可以从中更改用户的密码。
工作代码:
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.*;
import java.security.*;
public class ChangePassword {
DirContext ldapContext;
String baseName = ",OU=Crowd,DC=Domain,DC=local";
String serverIP = "xxx.xxx.xx.xxx";
public ChangePassword() {
try {
Hashtable ldapEnv = new Hashtable(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, "ldaps://" + serverIP + ":636");
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=adminUser" + baseName);
ldapEnv.put(Context.SECURITY_CREDENTIALS, "Password1234!!");
//ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
ldapContext = new InitialDirContext(ldapEnv);
} catch (Exception e) {
System.out.println(" bind error: " + e);
e.printStackTrace();
System.exit(-1);
}
}
public void updatePassword(String username, String password) {
try {
String quotedPassword = "\"" + password + "\"";
char unicodePwd[] = quotedPassword.toCharArray();
byte pwdArray[] = new byte[unicodePwd.length * 2];
for (int i = 0; i < unicodePwd.length; i++) {
pwdArray[i * 2 + 1] = (byte) (unicodePwd[i] >>> 8);
pwdArray[i * 2 + 0] = (byte) (unicodePwd[i] & 0xff);
}
ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("UnicodePwd", pwdArray));
ldapContext.modifyAttributes("cn=" + username + baseName, mods);
} catch (Exception e) {
System.out.println("update password error: " + e);
System.exit(-1);
}
}
public static void main(String[] args) {
// Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// the keystore that holds trusted root certificates
System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files\\Java\\jdk1.7.0_79\\bin\\client.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.debug", "all");
ChangePassword adc = new ChangePassword();
adc.updatePassword("subuser", "Password!!");
System.out.println("Password changed successfully");
}
}
在这个独立代码中,我可以访问活动目录并可以更改密码。我在Spring MVC中尝试过相同的操作。我在util包中添加了LDAP连接代码。然后我从控制器调用util类方法。我已经在控制器方法中自动安装了util类。
**Util class Code:**
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.*;
import java.security.*;
@Component
public class GetLDAPConnection {
@Value("${ad.baseName}")
String baseName;
@Value("${ad.serverIP}")
String serverIP;
@Value("${ad.adminUser}")
String adminUser;
@Value("${ad.adminPassword}")
String adminPassword;
@Value("${ad.propertyStoreKey}")
String propertyStoreKey;
@Value("${ad.propertyStorePath}")
String propertyStorePath;
@Value("${ad.propertyTrustStore}")
String propertyTrustStore;
@Value("${ad.propertyTrustStorePass}")
String propertyTrustStorePass;
@Value("${ad.propertyDebug}")
String propertyDebug;
@Value("${ad.propertyDebugValue}")
String propertyDebugValue;
DirContext ldapContext;
/*String baseName = ",OU=Crowd,DC=Domain,DC=local";
String serverIP = "192.168.50.164";*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void updatePassword(String username, String password) {
try {
System.out.println("adminUser :"+adminUser);
System.out.println("serverIP :"+serverIP);
System.out.println("baseName :"+baseName);
System.out.println("adminPassword "+adminPassword);
Hashtable ldapEnv = new Hashtable();
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, "ldaps://" + serverIP + ":636");
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=" + adminUser + baseName);
ldapEnv.put(Context.SECURITY_CREDENTIALS, adminPassword);
// ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
ldapContext = new InitialDirContext(ldapEnv);
System.out.println(ldapContext.getEnvironment());
System.out.println(ldapContext.getNameInNamespace());
Attributes attrs = ldapContext.getAttributes("dc=Domain,dc=local");
System.out.println("ALL Data: " + attrs.toString());
String quotedPassword = "\"" + password + "\"";
char unicodePwd[] = quotedPassword.toCharArray();
byte pwdArray[] = new byte[unicodePwd.length * 2];
for (int i = 0; i < unicodePwd.length; i++) {
pwdArray[i * 2 + 1] = (byte) (unicodePwd[i] >>> 8);
pwdArray[i * 2 + 0] = (byte) (unicodePwd[i] & 0xff);
}
ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("UnicodePwd", pwdArray));
ldapContext.modifyAttributes("cn=" + username + baseName, mods);
} catch (Exception e) {
System.out.println(" bind error: " + e);
e.printStackTrace();
System.exit(-1);
}
}
}
我正在从属性文件中读取配置。
属性文件:
ad.baseName=,OU=Crowd,DC=Domain,DC=local
ad.serverIP=xxx.xxx.xx.xxx
ad.adminUser=adminUser
ad.adminPassword=Password1234!!
ad.propertyStoreKey=javax.net.ssl.trustStore
ad.propertyStorePath=C:\\Program Files\\Java\\jdk1.7.0_79\\bin\\client.jks
ad.propertyTrustStore=javax.net.ssl.trustStorePassword
ad.propertyTrustStorePass=changeit
ad.propertyDebug=javax.net.debug
ad.propertyDebugValue=all
我收到了异常
绑定错误:javax.naming.NameNotFoundException:[LDAP:错误代码32 - 0000208D:NameErr:DSID-03100238,问题2001(NO_OBJECT),数据0,最佳匹配: 'OU =人群中,DC = DOMAIN,DC =本地' 剩余名称'cn = null,OU = Crowd,DC = Domain,DC = local' javax.naming.NameNotFoundException:[LDAP:错误代码32 - 0000208D:NameErr:DSID-03100238,问题2001(NO_OBJECT),数据0,最佳匹配: 'OU =人群中,DC = DOMAIN,DC =本地'
我收到“javax.naming.NameNotFoundException”,因为CN = null正在追加。任何人都可以解释这是什么问题。我可以读取属性文件并打印出值。但问题只出现在这些方面。我甚至进行了硬编码和检查,但它确实有效。
ldapEnv.put(Context.SECURITY_PRINCIPAL,“cn =”+ adminUser + baseName); ldapEnv.put(Context.SECURITY_CREDENTIALS,adminPassword);
任何人都可以告诉我这里的问题是什么