Attachment 'LdapTlsContextFactory.java'

Download

   1 package dummy;
   2 
   3 import java.io.IOException;
   4 import java.lang.reflect.InvocationHandler;
   5 import java.lang.reflect.InvocationTargetException;
   6 import java.lang.reflect.Method;
   7 import java.lang.reflect.Proxy;
   8 import java.util.Arrays;
   9 import java.util.HashMap;
  10 import java.util.Hashtable;
  11 import java.util.Map;
  12 import java.util.logging.Logger;
  13 
  14 import javax.naming.Context;
  15 import javax.naming.NamingException;
  16 import javax.naming.directory.DirContext;
  17 import javax.naming.ldap.InitialLdapContext;
  18 import javax.naming.ldap.LdapContext;
  19 import javax.naming.ldap.StartTlsRequest;
  20 import javax.naming.ldap.StartTlsResponse;
  21 import javax.naming.spi.InitialContextFactory;
  22 import javax.net.ssl.HostnameVerifier;
  23 import javax.net.ssl.SSLSession;
  24 
  25 import com.sun.jndi.ldap.LdapCtxFactory;
  26 
  27 public class LdapTlsContextFactory implements InitialContextFactory {
  28 
  29 	private static final class ProxyLdapContext implements InvocationHandler {
  30 		private final LdapContext delegate;
  31 		private final StartTlsResponse tls;
  32 
  33 		@SuppressWarnings("unchecked")
  34 		private ProxyLdapContext(Hashtable env) throws NamingException {
  35 			Map<String, Object> savedEnv = new HashMap<String, Object>();
  36 			for (String key : Arrays.asList(Context.SECURITY_AUTHENTICATION,
  37 					Context.SECURITY_CREDENTIALS, Context.SECURITY_PRINCIPAL,
  38 					Context.SECURITY_PROTOCOL)) {
  39 				Object entry = env.remove(key);
  40 				if (entry != null) {
  41 					savedEnv.put(key, entry);
  42 				}
  43 			}
  44 			delegate = new InitialLdapContext(env, null);
  45 			tls = (StartTlsResponse) delegate
  46 					.extendedOperation(new StartTlsRequest());
  47 			tls.setHostnameVerifier(new HostnameVerifier() {
  48 
  49 				@Override
  50 				public boolean verify(String hostname, SSLSession session) {
  51 					return true;
  52 				}
  53 			});
  54 			try {
  55 				SSLSession negotiate = tls.negotiate();
  56 				Logger.getLogger(this.getClass().getCanonicalName()).fine(
  57 						"LDAP is now using " + negotiate.getProtocol());
  58 			} catch (IOException e) {
  59 				throw new NamingException(e.getMessage());
  60 			}
  61 			for (Map.Entry<String, Object> savedEntry : savedEnv.entrySet()) {
  62 				delegate.addToEnvironment(savedEntry.getKey(), savedEntry
  63 						.getValue());
  64 			}
  65 		}
  66 
  67 		@Override
  68 		public Object invoke(Object proxy, Method method, Object[] args)
  69 				throws Throwable {
  70 			if ("close".equals(method.getName())) {
  71 				return doClose(delegate);
  72 			}
  73 			return method.invoke(delegate, args);
  74 		}
  75 
  76 		private Object doClose(LdapContext delegate) throws IOException,
  77 				IllegalAccessException, InvocationTargetException {
  78 			try {
  79 				if (tls != null) {
  80 					try {
  81 						tls.close();
  82 					} catch (IOException e) {
  83 						throw new InvocationTargetException(e);
  84 					}
  85 				}
  86 			} finally {
  87 				try {
  88 					if (delegate != null) {
  89 						delegate.close();
  90 					}
  91 				} catch (NamingException e) {
  92 					throw new InvocationTargetException(e);
  93 				}
  94 			}
  95 			return null;
  96 		}
  97 	}
  98 
  99 	public static final String REAL_INITIAL_CONTEXT_FACTORY = "REAL_INITIAL_CONTEXT_FACTORY";
 100 
 101 	@SuppressWarnings("unchecked")
 102 	@Override
 103 	public Context getInitialContext(final Hashtable environment)
 104 			throws NamingException {
 105 		final Hashtable proxyEnv = new Hashtable(environment);
 106 		Object realFactory;
 107 		if (environment.contains(REAL_INITIAL_CONTEXT_FACTORY)) {
 108 			realFactory = environment.get(REAL_INITIAL_CONTEXT_FACTORY);
 109 		} else {
 110 			realFactory = LdapCtxFactory.class.getCanonicalName();
 111 		}
 112 		proxyEnv.put(Context.INITIAL_CONTEXT_FACTORY, realFactory);
 113 		proxyEnv.put("com.sun.jndi.ldap.connect.pool", "false");
 114 		return (Context) Proxy.newProxyInstance(this.getClass()
 115 				.getClassLoader(), new Class<?>[] { DirContext.class },
 116 				new ProxyLdapContext(proxyEnv));
 117 	}
 118 
 119 }

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.