Java to Active Directory

JNDI is for real and it works, but the key to remember when writing a Java or JSP/Servlet page to get to Microsoft Active Directory is........ use the secure LDAP server to the Active Directory setup by the Wintel group in your company. I'll outline the code you will need but pay close attention to the port. You'll see a lot of stuff on the web that tells you can can go http, but you can't change any values unless you have SSL certs between your webserver and the AD server, and you MUST use the SSL, secure connection to the LDAP AD server to make anything work right. Let's start with the includes (JSP version):

<%@ page import="java.util.Hashtable" %> 
<%@ page import="javax.naming.*" %> 
<%@ page import="javax.naming.ldap.*" %> 
<%@ page import="javax.naming.directory.*" %> 
<%@ page import="java.io.*" %> 
<%@ page import="sun.misc.BASE64Encoder" %> 
<%@ page import="sun.misc.BASE64Decoder" %> 
<%@ page import="java.io.BufferedInputStream" %> 
<%@ page import="java.io.BufferedReader" %> 
<%@ page import="java.io.IOException" %> 
<%@ page import="java.io.InputStream" %> 
<%@ page import="java.io.InputStreamReader" %>

The next step outlines your connection and how you will be issuing commands to the AD:

String  Domain = "@YOURDOMAIN";
        String  UserLogin = request.getParameter("loginID")+Domain;
        String  WinLoginID = "CN="+request.getParameter("loginID")+",OU=DOMAIN,OU=DOMAIN info,OU=Users,OU=MORE INFO,OU=EVEN MORE INFO,DC=Name";
// --### Log on to the LDAP server as Self

                                Hashtable env = new Hashtable();
                                System.setProperty("javax.net.ssl.trustStore", keystore);
                                env.put(Context.INITIAL_CONTEXT_FACTORY,
                                        "com.sun.jndi.ldap.LdapCtxFactory");
                                env.put(Context.PROVIDER_URL, "ldap://YOUR_SERVER:636"); //389
                                env.put(Context.SECURITY_PROTOCOL, "ssl");

                                env.put(Context.SECURITY_AUTHENTICATION, "simple");
                                env.put(Context.SECURITY_PRINCIPAL, UserLogin);
                                env.put(Context.SECURITY_CREDENTIALS, OldPswd);


                                try {

                                DirContext ctx = new InitialDirContext(env);

                                // --## change password is a single ldap modify operation
                                // --## that deletes the old password and adds the new password

                                ModificationItem[] mods = new ModificationItem[2];

                                // --## Firstly delete the "unicdodePwd" attribute, using the old password
                                // --## Then add the new password,Passwords must be both Unicode 
                                // --## and a quoted string
                                String oldQuotedPassword = "\"" + OldPswd + "\"";
                                byte[] oldUnicodePassword = oldQuotedPassword.getBytes("UTF-16LE");
                                String newQuotedPassword = "\"" + NewPswd + "\"";
                                byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");


                                mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("unicodePwd", oldUnicodePassword));
                                mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));

                                // --## Perform the update

                                ctx.modifyAttributes(WinLoginID, mods);

                                ctx.close();

The example code you see above is for changing your own password logged on as yourself (a real user), but you can issue commands for the ctx object in any way you like. This code works in a very locked down environment, so you can be sure it will work with yours if properly setup by your Wintel Admins. Remember to get the certs from your AD server and import them to the WEBSERVER you are using - it will normally be in the environment that is set for your JRE - find that physical directory and place the certs in the cacerts directory by doing a proper import.

Contact: daquijne@josephdaqui.com (copyright 2010)