在做统一用户相关系统时,要定时从ad域同步账号。
ldap连接ad域时有两种方式,通过389端口和636端口。当进行基础操作时,如查询用户和组织信息等,通过389端口访问即可。但与密码等相关操作必须要从636端口ssl访问才可以。当访问636端口时强制要求有证书,较为繁琐,还有一种面免证书的方式。
主要使用一个DummySSLSocketFactory工具类。
DummySSLSocketFactory工具类:

package com.koron.sync;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

public class DummySSLSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory factory;
    
    public DummySSLSocketFactory() {
    
        try {
        
        SSLContext sslcontext = SSLContext.getInstance("TLS");
        
        sslcontext.init( null, // No KeyManager required
        
        new TrustManager[] { new DummyTrustManager()},
        
        new java.security.SecureRandom());
        
        factory = ( SSLSocketFactory) sslcontext.getSocketFactory();
        
        } catch( Exception ex) { ex.printStackTrace(); }
    
    }
    
    public static SocketFactory getDefault() {
    
    return new DummySSLSocketFactory();
    
    }
    
    public Socket createSocket( Socket socket, String s, int i, boolean flag) throws IOException {
    
    return factory.createSocket( socket, s, i, flag);
    
    }
    
    public Socket createSocket( InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
    
    return factory.createSocket( inaddr, i, inaddr1, j);
    
    }
    
    public Socket createSocket( InetAddress inaddr, int i) throws IOException {
    
    return factory.createSocket( inaddr, i);
    
    }
    
    public Socket createSocket( String s, int i, InetAddress inaddr, int j) throws IOException {
    
    return factory.createSocket( s, i, inaddr, j);
    
    }
    
    public Socket createSocket( String s, int i) throws IOException {
    
    return factory.createSocket( s, i);
    
    }
    
    public String[] getDefaultCipherSuites() {
    
    return factory.getSupportedCipherSuites();
    
    }
    
    public String[] getSupportedCipherSuites() {
    
    return factory.getSupportedCipherSuites();
    
    }

}

然后进行正常修改操作即可
首先连接ad域
连接超时的限制会报错,不清楚什么原因,注释掉就不报错了。。。

    /*********登录*****/
    @Test
    public void  connectNossl() {
        System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");
        ADInfo info = new ADInfo();
        String username = new String();
        username = "dog@test.local";
        String password = new String();
        password = "TEST00003";
        String host = info.getHost();
        int port = info.getPort();
        DirContext ctx = null;
        Hashtable<String, String> HashEnv = new Hashtable<>();
        HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别(none,simple,strong)
        HashEnv.put(Context.SECURITY_PRINCIPAL, username); // AD的用户名
        HashEnv.put(Context.SECURITY_CREDENTIALS, password); // AD的密码
        HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
        //HashEnv.put("com.sun.jndi.ldap.connect.timeout", "3000");// 连接超时设置为3秒
        // HashEnv.put(Context.PROVIDER_URL, "ldap://" + GROUP_HOST + ":" + GROUP_PORT);// 默认端口389
        HashEnv.put(Context.PROVIDER_URL,"ldaps://输入地址:636" );
        HashEnv.put(Context.SECURITY_PROTOCOL, "ssl");
        HashEnv.put("java.naming.ldap.factory.socket", "com.koron.sync.DummySSLSocketFactory");
        try {
            System.out.println("芜湖~~身份验证成功!");
            Control[] sortConnCtls = new Control[1];
            sortConnCtls[0] = new SortControl("sAMAccountName", Control.CRITICAL);
            this.ctx = new InitialLdapContext(HashEnv,sortConnCtls);// 初始化上下文
            System.out.println("当前密码:"+password);           ctx.close();
////            updateUserPassword();
//            //return ctx;
        } catch (AuthenticationException e) {
            System.out.println("身份验证失败!");
            e.printStackTrace();
        } catch (javax.naming.CommunicationException e) {
            System.out.println("AD域连接失败!");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("身份验证未知异常!");
            e.printStackTrace();
        } finally {
            if (null != ctx) {
                try {
                    ctx.close();
                    ctx = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        // return ctx;
    }

对密码操作,以修改密码为例

@Test
    /********密码相关*******/
    public void updateUserPassword() {
            String newPassword = new String();
            newPassword = "TEST00003";
        ModificationItem[] mods = new ModificationItem[1];

        String newQuotedPassword = "\"" + newPassword + "\"";

        byte[] newUnicodePassword = new byte[0];
        try {
            newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,

      new BasicAttribute("unicodePwd", newUnicodePassword));
        // 修改密码
        String userDN = "CN=dog,CN=Users,DC=test,DC=local";
        try {
            connectNossl();
            ctx.modifyAttributes(userDN, mods);
            System.out.println("密码修改成功,当前密码:"+newPassword);
        } catch (NamingException e) {
            e.printStackTrace();
        }

    }



    @Test
    public void Test2(){
        connectNossl();
        updateUserPassword();
   }
文章作者: Administrator
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ElIauk!
喜欢就支持一下吧