Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Querying Active Directory via Java

What is the best way to query Active Directory from Java?

Now I know that .NET has special methods built in for doing this sort of thing. But in Java, would calling a Powershell script by launching a process/command line be a good way of doing this?

Furthermore, why is the decision taken to call C# from Java anytime Java needs to access Windows WMI data? Is there a reason why running something like pstools (which can launch processes/commands on remote computers) from a command line called by Java, won't work?

Thanks

like image 414
GurdeepS Avatar asked Dec 21 '22 20:12

GurdeepS


2 Answers

Please referred the following code.

package active.security.util.ldap;

import java.util.Date;
import java.util.Hashtable;
import javax.naming.*;
import javax.naming.directory.*;
//import javax.naming.ldap.PagedResultsControl;

import active.security.util.DateTool;


public class JNDISearch {
    public static String INITCTX = "com.sun.jndi.ldap.LdapCtxFactory"; // driver
    public static String MY_HOST = "ldap://dcserver:389"; // server and port
    public static String MY_SEARCHBASE = "DC=active,DC=local"; // base DC
    public static String MY_FILTER = "(&(objectclass=User)(!(objectclass=computer)))"; // filter
    public static String MGR_DN = "domain\\username"; // username
    public static String MGR_PW = "password"; // password
    public static String MY_ATTRS[] = {/* "cn","userpassword","mail", */"cn" };
    public static String temp = new String();

    public static void main(String[] ags) throws Exception{
        new JNDISearch().search();
    }


    @SuppressWarnings({ "rawtypes", "unchecked" })
    public String search() throws Exception {

        int userCount = 0;
        Date begin = new Date();

        try {
            Hashtable env = new Hashtable();

            //PagedResultsControl control = new PagedResultsControl(5000, true);
            env.put(Context.INITIAL_CONTEXT_FACTORY, INITCTX);
            env.put(Context.PROVIDER_URL, MY_HOST);
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, MGR_DN);
            env.put(Context.SECURITY_CREDENTIALS, MGR_PW);
            DirContext ctx = new InitialDirContext(env);

            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration results = ctx.search(MY_SEARCHBASE, MY_FILTER,constraints);

            while (results != null && results.hasMore()) {
                SearchResult sr = (SearchResult) results.next();
                // String dn = sr.getName();
                String dn = sr.getName() + "," + MY_SEARCHBASE;

                Attributes ar = ctx.getAttributes(dn, MY_ATTRS);
                if (ar == null) {
                    System.out.println("Entry " + dn
                            + " has none of the specified attributes\n");
                } else {
                    Attribute attr = ar.get("cn");
                    String cn = (String)attr.get(0);
                    System.out.println(cn);

                }
                userCount++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            Date end = new Date();

            long seconds = DateTool.getSenconds(begin, end);

            System.out.println("total user: "+userCount);
            System.out.println("time cost: "+seconds+" seconds");

        }

        return null;

    }


}
like image 30
53iScott Avatar answered Dec 24 '22 09:12

53iScott


What is the best way to query Active Directory from Java?

I don't know if it is the BEST way, but the typical approach is to use LDAP. You can do this using JNDI. Examples of this can be found here.

Now I know that .NET has special methods built in for doing this sort of thing. But in Java, would calling a Powershell script by launching a process/command line be a good way of doing this?

That depends. I think some java folks would cringe at this as it is a pretty clear violation of the "write once, run anywhere" type mentality. However, if you can guarantee that your app will only be used on windows and you have no other alternatives then I don't see the harm.

Furthermore, why is the decision taken to call C# from Java anytime Java needs to access Windows WMI data? Is there a reason why running something like pstools (which can launch processes/commands on remote computers) from a command line called by Java, won't work?

I'm not particularly sure I know the answer to this one. I think I'd need to see some clear examples to take a crack it it.

I hope this helps.

like image 124
javamonkey79 Avatar answered Dec 24 '22 11:12

javamonkey79