我与AD有很好的联系。我可以验证并检查失败的auths的错误消息。
我遇到的问题来自于尝试更改密码。我此时已建立LDAPContext(是的,它是SSL连接)。问题来自于不知道在“username”参数中使用什么值。我已经尝试了所有我能想到的变化,最终得到了三个错误之一:
A)NO_OBJECT - 我假设这意味着它正确地连接到AD但无法找到我正在寻找的东西。
B)DIR_ERROR - 我假设这意味着它可以正确进入AD,但不知道wtf我希望它在那之后做。
C)某种类型的引用错误只有在我不符合DC的条件时才会发生,因此我认为这几乎是给定的。
以下是我正在使用的代码:
public void changePassword(String username, String password) {
ModificationItem[] mods = new ModificationItem[1];
String newQuotedPassword = "\"" + password + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes();
try {
newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
try {
ldapContext.modifyAttributes(username, mods);
} catch (NamingException e) {
System.out.println("Error changing password for '" + username + "': " + e.getMessage());
e.printStackTrace();
}
}
答案 0 :(得分:2)
Spring有LDAP module非常好用。我敢打赌,它会做你需要的。
答案 1 :(得分:1)
我们在这里提到了JNDI的Java http://ldapwiki.willeke.com/wiki/Set%20Active%20Directory%20Password%20From%20Java
答案 2 :(得分:0)
答案 3 :(得分:0)
这是一个有效的例子:
<强> Main.java:强>
package io.fouad.ldap;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
public class Main
{
public static void main(String[] args)
{
final String LDAP_SERVERS = "ldap://AD_SERVER:636 ldap://AD_SERVER2:636"; // separated by single spaces
final String LDAP_CONNECT_TIMEOUT_MS = "10000"; // 10 seconds
final String LDAP_READ_TIMEOUT_MS = "10000"; // 10 seconds
final String AUTHENTICATION_DOMAIN = "domain.com";
final String USERNAME = "username";
final String OLD_PASSWORD = "123";
final String NEW_PASSWORD = "456";
final String TARGET_BASE_DN = "dc=domain,dc=com";
Hashtable<String, String> ldapEnv = new Hashtable<>();
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, LDAP_SERVERS);
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put("java.naming.ldap.version", "3");
ldapEnv.put(Context.SECURITY_PRINCIPAL, USERNAME + "@" + AUTHENTICATION_DOMAIN);
ldapEnv.put(Context.SECURITY_CREDENTIALS, OLD_PASSWORD);
ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
ldapEnv.put("java.naming.ldap.factory.socket", "io.fouad.ldap.MySSLSocketFactory");
//ldapEnv.put("com.sun.jndi.ldap.connect.timeout", LDAP_CONNECT_TIMEOUT_MS);
//ldapEnv.put("com.sun.jndi.ldap.read.timeout", LDAP_READ_TIMEOUT_MS);
DirContext ldapContext = null;
try
{
ldapContext = new InitialDirContext(ldapEnv);
}
catch(AuthenticationException e)
{
System.out.println("Wrong username/password!");
e.printStackTrace();
}
catch(NamingException e)
{
e.printStackTrace();
}
if(ldapContext == null) return;
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration objects = null;
try
{
objects = ldapContext.search(TARGET_BASE_DN, String.format("(&(objectClass=user)(sAMAccountName=%s))", USERNAME), searchControls);
}
catch(NamingException e)
{
e.printStackTrace();
}
if(objects == null) return;
try
{
if(objects.hasMore())
{
SearchResult entry = (SearchResult) objects.next();
ModificationItem[] mods = new ModificationItem[2];
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("unicodePwd", getPasswordByteArray(OLD_PASSWORD)));
mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("unicodePwd", getPasswordByteArray(NEW_PASSWORD)));
ldapContext.modifyAttributes(entry.getName() + "," + TARGET_BASE_DN, mods);
System.out.println("Successfully changed the password!");
}
else
{
System.out.println("User (" + USERNAME + ") was not found!");
}
}
catch(NamingException e)
{
e.printStackTrace();
}
System.out.println("DONE!");
}
private static byte[] getPasswordByteArray(String password)
{
String quotedPassword = "\"" + password + "\"";
try
{
return quotedPassword.getBytes("UTF-16LE");
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
return null;
}
}
}
MySSLSocketFactory.java:(使用它需要您自担风险)
package io.fouad.ldap;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
public class MySSLSocketFactory extends SSLSocketFactory
{
private SSLSocketFactory socketFactory;
public MySSLSocketFactory()
{
try
{
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] {new X509TrustManager()
{
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s){}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s){}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}}, new SecureRandom());
socketFactory = ctx.getSocketFactory();
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
}
}
public static SocketFactory getDefault()
{
return new MySSLSocketFactory();
}
@Override
public String[] getDefaultCipherSuites()
{
return socketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites()
{
return socketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException
{
return socketFactory.createSocket(socket, string, i, bln);
}
@Override
public Socket createSocket(String string, int i) throws IOException
{
return socketFactory.createSocket(string, i);
}
@Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException
{
return socketFactory.createSocket(string, i, ia, i1);
}
@Override
public Socket createSocket(InetAddress ia, int i) throws IOException
{
return socketFactory.createSocket(ia, i);
}
@Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException
{
return socketFactory.createSocket(ia, i, ia1, i1);
}
}