原文作者放最后了(但不得不吐槽一下他,排版太TM乱了)
本文摘抄网上他人的智慧,只做了一点汇总和修改。
对于ad用户的普通管理都可以用 389端口进行修改,对于密码是在我的测试中是不能修改的,
对于 属性 userPassword 用389端口去设置,虽然能创建成功,但是致使创建的用户,不能登录,登录提示 用户名和密码错误。及时登录ad服务器手动去重置他的密码也是会提示用户名和密码错误的。
在网上搜索了很多内容,采用636 端口 去修改
逻辑是,先创建一个无密码的账户,然后去修改密码(属性为unicodePwd)
636端口为ssl协议需要用到证书,但是,搜到网上 不用导入jdk证书,免证书连接636端口,如下就是代码
package cipher.console.oidc;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
public class CreateADRequest {
private static final Logger LOG = LoggerFactory.getLogger(CreateADRequest.class);
private static LdapContext ctx =null;
public static void LDAP_connect(ADConfig adConfig) {
String url = new String("ldaps://" + adConfig.getAD_SERVER() + ":" + adConfig.getAD_SERVER_PORT());
// Hashtable env = new Hashtable();
//
// env.put(Context.SECURITY_AUTHENTICATION, "simple");
// env.put(Context.SECURITY_PRINCIPAL, adConfig.getAD_ACCOUNT()+"@"+adConfig.getDN());
// env.put(Context.SECURITY_CREDENTIALS, adConfig.getAD_PASSWORD());
// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// env.put(Context.REFERRAL,"follow");
// env.put("com.sun.jndi.ldap.read.timeout","6000");
// env.put(Context.PROVIDER_URL, url);
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.setProperty(Context.PROVIDER_URL, url);
props.put("java.naming.ldap.factory.socket", "com.zhongan.ua.utils.LTSSSLSocketFactory");
props.put(Context.SECURITY_PROTOCOL, "ssl"); //389端口 就去掉
props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
props.setProperty(Context.REFERRAL, "ignore");
props.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
props.setProperty(Context.SECURITY_PRINCIPAL, adConfig.getAD_ACCOUNT());
props.setProperty(Context.SECURITY_CREDENTIALS, adConfig.getAD_PASSWORD());
try {
ctx = new InitialLdapContext(props, null);
// ctx = new InitialDirContext(env);
} catch (Exception err) {
LOG.info("ad服务器连接异常", err);
}
}
public static void closeContext() {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
LOG.info("ad服务器关闭异常", e);
}
}
}
public static Boolean getUserDN(String type, String filter, String name, ADConfig adConfig) {
String userName = name;
if (userName == null || "".equals(userName)) {
return false;
}
try {
String searchFilter = "(&(objectClass=" + escapeLDAPSearchFilter(type) + ")(" + escapeLDAPSearchFilter(filter) + "=" + escapeLDAPSearchFilter(name) + "))";
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String returnedAtts[] = {"memberOf"};
searchCtls.setReturningAttributes(returnedAtts);
NamingEnumeration answer = ctx.search(escapeDN(adConfig.getBASEDN()), searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
Attributes Attrs = sr.getAttributes();
if (Attrs != null) {
return true;
}
}
} catch (NamingException e) {
LOG.info("获取UserDN失败", e);
return false;
}
return false;
}
public static boolean addAdUser(String userName, String pwd, String description, ADConfig adConfig) {
String userDN = "CN=" + userName + "," + adConfig.getBASEDN();
try {
LDAP_connect(adConfig);
BasicAttributes attrsbu = new BasicAttributes();
BasicAttribute objclassSet = new BasicAttribute("objectclass");
objclassSet.add("User");
attrsbu.put(objclassSet);
// attrsbu.put("sn", userName);
// attrsbu.put("cn", userName);
attrsbu.put("uid", userDN);
// attrsbu.put("userPassword", pwd);
attrsbu.put("description", description);
attrsbu.put("userAccountControl", "544");
attrsbu.put("userPrincipalName", userName + "@" + adConfig.getDN());
attrsbu.put("pwdLastSet", "-1");
attrsbu.put("sAMAccountName", userName);
attrsbu.put("displayName", userName);
ctx.createSubcontext(userDN, attrsbu);
ModificationItem[] mods = new ModificationItem[1];
String newQuotedPassword = "\"" + pwd + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
// 修改密码
ctx.modifyAttributes(userDN, mods);
return true;
// }
} catch (NamingException ex) {
LOG.info("添加用户异常:", ex);
} catch (Exception e) {
LOG.info("添加用户异常:", e);
} finally {
closeContext();
}
return false;
}
public static boolean delAdUser(String userName, ADConfig adConfig) {
String userDN = "CN=" + userName + "," + adConfig.getBASEDN();
try {
LDAP_connect(adConfig);
// if(getUserDN("user","CN",userName,adConfig)) {
ctx.destroySubcontext(userDN);
return true;
// }
} catch (NamingException e) {
LOG.info("删除用户异常:", e);
} catch (Exception e) {
LOG.info("删除用户异常:", e);
} finally {
closeContext();
}
return false;
}
public static boolean enableUser(String userName, ADConfig adConfig) {
String userDN = "CN=" + userName + "," + adConfig.getBASEDN();
try {
LDAP_connect(adConfig);
if (getUserDN("user", "CN", userName, adConfig)) {
BasicAttributes attrsbu = new BasicAttributes();
attrsbu.remove("CN");
attrsbu.put("userAccountControl", "544");
ctx.modifyAttributes(userDN, DirContext.REPLACE_ATTRIBUTE, attrsbu);
return true;
}
} catch (NamingException e) {
LOG.info("启用用户异常:", e);
} catch (Exception e) {
LOG.info("启用用户异常:", e);
} finally {
closeContext();
}
return false;
}
public static boolean disableUser(String userName, ADConfig adConfig) {
String userDN = "CN=" + userName + "," + adConfig.getBASEDN();
try {
LDAP_connect(adConfig);
if (getUserDN("user", "CN", userName, adConfig)) {
BasicAttributes attrsbu = new BasicAttributes();
attrsbu.remove("CN");
attrsbu.put("userAccountControl", "514");
ctx.modifyAttributes(userDN, DirContext.REPLACE_ATTRIBUTE, attrsbu);
return true;
}
} catch (NamingException e) {
LOG.info("禁用用户异常:", e);
} catch (Exception e) {
LOG.info("禁用用户异常:", e);
} finally {
closeContext();
}
return false;
}
public static String listADInfo(String type, ADConfig adConfig) {
String result = "";
try {
LDAP_connect(adConfig);
String searchBase = "DC=test,DC=com";
String searchFilter = "objectClass=" + escapeLDAPSearchFilter(type) + "";
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String returnedAtts[] = {"memberOf"}; // 定制返回属性
searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集 不设置则返回所有属性
// 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);// Search for objects using the filter
while (answer.hasMore()) {
SearchResult result1 = (SearchResult) answer.next();
System.err.println(result1.getName());
NamingEnumeration attrs = result1.getAttributes().getAll();
while (attrs.hasMore()) {
Attribute attr = attrs.next();
System.out.println(attr.getID() + " = " + attr.get());
}
}
} catch (NamingException e) {
LOG.info("获取用户列表失败", e);
} finally {
closeContext();
}
return result;
}
public static String escapeDN(String name) {
StringBuffer sb = new StringBuffer(); // If using JDK >= 1.5 consider using StringBuilder
if ((name.length() > 0) && ((name.charAt(0) == ' ') || (name.charAt(0) == '#'))) {
sb.append('\\'); // add the leading backslash if needed
}
for (int i = 0; i < name.length(); i++) {
char curChar = name.charAt(i);
switch (curChar) {
case '\\':
sb.append("\\\\");
break;
case ',':
sb.append("\\,");
break;
case '+':
sb.append("\\+");
break;
case '"':
sb.append("\\\"");
break;
case '<':
sb.append("\\<");
break;
case '>':
sb.append("\\>");
break;
case ';':
sb.append("\\;");
break;
default:
sb.append(curChar);
}
}
if ((name.length() > 1) && (name.charAt(name.length() - 1) == ' ')) {
sb.insert(sb.length() - 1, '\\'); // add the trailing backslash if needed
}
return sb.toString();
}
public static final String escapeLDAPSearchFilter(String filter) {
StringBuffer sb = new StringBuffer(); // If using JDK >= 1.5 consider using StringBuilder
for (int i = 0; i < filter.length(); i++) {
char curChar = filter.charAt(i);
switch (curChar) {
case '\\':
sb.append("\\5c");
break;
case '*':
sb.append("\\2a");
break;
case '(':
sb.append("\\28");
break;
case ')':
sb.append("\\29");
break;
case '\u0000':
sb.append("\\00");
break;
default:
sb.append(curChar);
}
}
return sb.toString();
}
}
免证书的类 来了
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
public class LTSSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory socketFactory;
public LTSSSLSocketFactory() {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[]{new LTSTrustmanager()}, new SecureRandom());
socketFactory = ctx.getSocketFactory();
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
}
public static SocketFactory getDefault() {
return new LTSSSLSocketFactory();
}
@Override
public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3) throws IOException {
return null;
}
@Override
public String[] getDefaultCipherSuites() {
return socketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return socketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
return socketFactory.createSocket(arg0, arg1);
}
@Override
public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
return socketFactory.createSocket(arg0, arg1);
}
@Override
public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) throws IOException, UnknownHostException {
return socketFactory.createSocket(arg0, arg1, arg2, arg3);
}
@Override
public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
return socketFactory.createSocket(arg0, arg1, arg2, arg3);
}
}
另一个类:
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class LTSTrustmanager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public X509Certificate[]getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}
作者:自然卷_4475
链接:https://www.jianshu.com/p/76cfff18d523
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
网友评论