LDAP,LDAPS

java LdapTest "ldap://ldapserver|username|ou=users,o=owner,c=com|cn=user,ou=admin,o=owner,c=com|username|password"
java LdapTest "ldaps://ldapserver|username|ou=users,o=owner,c=com|cn=user,ou=admin,o=owner,c=com|username|password"
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

public class LdapTest {

  	//https://gist.github.com/jbarber/2909828
	public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException {
		if (null == args || args.length == 0) {
			System.out.println("please input parameter");
			return;
		}
		String parameter = args[0];
		System.out.println("parameter:" + parameter);
		String[] parameters = parameter.split("\\|");
		if (parameters.length != 6) {
			System.out.println("parameter length:" + parameters.length);
			System.out.println("please input right parameter");
			return;
		}
		String providerUrl = parameters[0];
		String securityCredentials = parameters[1];
		String baseDn = parameters[2];
		String connectDn = parameters[3];
		String usrId = parameters[4];
		String pwd = parameters[5];
		
		Hashtable<String, String> env = new Hashtable<String, String>();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, providerUrl);
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		env.put(Context.SECURITY_PRINCIPAL, connectDn);
		env.put(Context.SECURITY_CREDENTIALS, securityCredentials);

		if(providerUrl.startWith("ldaps")){
			env.put(Context.SECURITY_PROTOCOL, "ssl");
			System.setProperty("javax.net.ssl.trustStore", "keystore file path");
			System.setProperty("javax.net.ssl.trustStorePassword", "keystore password");

			//https://stackoverflow.com/questions/58911874/java-upgrade-8-to-11-causing-issue-with-ldaps-connection-connection-or-outbound
			System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");

			//https://qiita.com/n-i-e/items/41673fd16d7bd1189a29
			//https://stackoverflow.com/questions/4615163/how-to-accept-self-signed-certificates-for-jndi-ldap-connections
			//https://kazuhira-r.hatenablog.com/entry/20180513/1526223561
			//https://stackoverflow.com/questions/7812444/how-do-i-import-an-existing-java-keystore-jks-file-into-a-java-installation
			//https://stackoverflow.com/questions/12893995/how-to-check-certificate-name-and-alias-in-keystore-files
			env.put("java.naming.ldap.factory.socket","Factory");
		}

		DirContext dirContextAdmin = null;
		DirContext dirContextUser = null;
		try {
			dirContextAdmin = new InitialDirContext(env);
			SearchControls searchControls = new SearchControls();
			searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			String filter = "cn=";
			NamingEnumeration<SearchResult> searchResult = dirContextAdmin.search(baseDn, filter + usrId, searchControls);
			if (searchResult.hasMoreElements()) {
				SearchResult sr = (SearchResult) searchResult.nextElement();
				String userName = sr.getName();
				System.out.println("userName:" + userName);
				Attributes attributes = sr.getAttributes();
				NamingEnumeration<? extends Attribute> all = attributes.getAll();
				if(all.hasMore()) {
					Attribute attribute = all.nextElement();
					System.out.println(attribute.getID() + ":" + attribute.toString());
				}
				env.put(Context.SECURITY_PRINCIPAL, userName + "," + baseDn);
				env.put(Context.SECURITY_CREDENTIALS, pwd);
				dirContextUser = new InitialDirContext(env);
			}
		} catch (NamingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (dirContextUser != null) {
					dirContextUser.close();
				}
			} catch (NamingException e) {
				e.printStackTrace();
			}
			try {
				if (dirContextAdmin != null) {
					dirContextAdmin.close();
				}
			} catch (NamingException e) {
				e.printStackTrace();
			}
		}
	}

	static class Factory extends SSLSocketFactory {
	    SSLSocketFactory delegate;

	    public Factory() {
	        try {
	            SSLContext sslContext = SSLContext.getInstance("SSL");
	            sslContext.init(null,
	                    new X509TrustManager[]{
	                            new X509TrustManager() {
	                                @Override
	                                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	                                }

	                                @Override
	                                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	                                }

	                                @Override
	                                public X509Certificate[] getAcceptedIssuers() {
	                                    return null;
	                                }
	                            }
	                    },
	                    new SecureRandom());

	            delegate = sslContext.getSocketFactory();
	        } catch (Exception e) {
	            throw new RuntimeException(e);
	        }
	    }

	    @Override
	    public String[] getDefaultCipherSuites() {
	        return delegate.getDefaultCipherSuites();
	    }

	    @Override
	    public String[] getSupportedCipherSuites() {
	        return delegate.getSupportedCipherSuites();
	    }

	    @Override
	    public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
	        return delegate.createSocket(socket, s, i, b);
	    }

	    @Override
	    public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
	        return delegate.createSocket(s, i);
	    }

	    @Override
	    public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
	        return delegate.createSocket(s, i, inetAddress, i1);
	    }

	    @Override
	    public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
	        return delegate.createSocket(inetAddress, i);
	    }

	    @Override
	    public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
	        return delegate.createSocket(inetAddress, i, inetAddress1, i1);
	    }

	    public static SocketFactory getDefault() {
	        return new Factory();
	    }
	}

}