美文网首页
AD域免证书改密码(转载重排)

AD域免证书改密码(转载重排)

作者: 南柯一梦00 | 来源:发表于2018-11-10 11:07 被阅读14次

原文作者放最后了(但不得不吐槽一下他,排版太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
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

相关文章

网友评论

      本文标题:AD域免证书改密码(转载重排)

      本文链接:https://www.haomeiwen.com/subject/vbkzxqtx.html