2

I'm using JNDI library to access to an AD from Java Webapp. I authenticate agaisnt the AD via LDAP using a technical user as follows:

    Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
    ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT);
    ldapEnv.put(Context.PROVIDER_URL, providerUrl);
    ldapEnv.put(Context.SECURITY_AUTHENTICATION,
            SECURITY_AUTHENTICATION_SIMPLE);
    ldapEnv.put(Context.SECURITY_PRINCIPAL, principal);
    ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials);
    return new InitialDirContext(ldapEnv);

I use this user to read and write from/to AD.

But after that, I don't know how to authenticate the final user who is really accessing to my webapp with his user and a password.

I read about using find method from Context class but I'm not sure how to do or how to build the the search filter. For example

(&(cn= ....

I don't know either how to find for all users in the AD. I would like to show in my webapp a list of all available users in AD

Rafa Romero
  • 2,667
  • 5
  • 25
  • 51

5 Answers5

4

-To Authenticate a user

Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "LDAP://url/");

env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "domain\\user_name");
env.put(Context.SECURITY_CREDENTIALS, "password");

InitialLdapContext ctx = new InitialLdapContext(env,null);
boolean authenticated = (ctx != null) ? true : false;

-To Get all users' names

public ArrayList<String> getAllUsers(LdapContext ctx) {
    ArrayList<String> users = new ArrayList<>();
    try {
        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

        String[] attrIDs = {"cn"};
        constraints.setReturningAttributes(attrIDs);

        NamingEnumeration answer = ctx.search("dc=example,dc=com", "(&(cn=*))", constraints);

        while (answer.hasMore()) {
            Attributes attrs = ((SearchResult) answer.next()).getAttributes();
            users.add(attrs.get("cn").toString().replace("cn:", ""));
        }

    } catch (Exception ex) {
    }
    return users;
}

-To Search a particular use

public String getUserName(String username, LdapContext ctx) {
    try {
        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

        String[] attrIDs = {"cn"};
        constraints.setReturningAttributes(attrIDs);

        NamingEnumeration answer = ctx.search("OU=Employees,OU=Users,DC=sub_domain,DC=domain,DC=com", "uid=" + username, constraints);

        if (answer.hasMore()) {
            Attributes attrs = ((SearchResult) answer.next()).getAttributes();
            return attrs.get("cn").toString().replace("cn:", "");
        } else {
            return null;
        }

    } catch (Exception ex) {
    }
    return null;
}

You can get more details about search query from this

Sanira
  • 334
  • 3
  • 7
2

Why don't you use the same for each user to authenticate.

see http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html

If you get the context for that user, that means username & password is correct. If not, not you get the exception & send it o user login screen etc.

Don't forget to close the Context in finally block if authenticated.

Gokhan Oner
  • 3,237
  • 19
  • 25
2

I believe this link will save your day:
http://www.javaxt.com/Tutorials/Windows/How_to_Authenticate_Users_with_Active_Directory You can authenticate a user and list users of a domain.

elsadek
  • 1,028
  • 12
  • 39
2

-To authenticate you need to create dir context , just like you mentioned in you question, for each user trying to to login.

--Or if you have Weblogic as your Appserver , you can make use of WL container authentication to handle user login by configuring AD as an authenticatoe in WL and protecting your login URL. : Read more Configuring container-managed security in Weblogic

-To list all users under a Root DSE or a certain Base DN

  1. Create a Dir Context to pointing to the Root DSE or a DN under it

    DirContext ctx = InitialDirContext(ldapEnv);

  2. Do context.search() passing returning attributes, search controls and the search filter matching user object classes and login attribute

    SearchControls controls = new SearchControls(); controls.setReturningAttributes(new String[]{"cn" ,"objectGUID"}); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); String filter = "(&(cn=*)(|(objectclass=person) (objectclass=organizationalPerson)))";

    NamingEnumeration searchResult = ctx.search("", filter, controls);

-To search a particular user , modify the filter to match the user cn or any other attribute

String filter = "(&(cn=Rafa Romero)(|(objectclass=person)(objectclass=organizationalPerson)))";
Community
  • 1
  • 1
Roshith
  • 2,116
  • 13
  • 21
2

Most servlet containers can be configured to authenticate via LDAP, that would be significantly more secure and reliable than rolling your own authentication code.

For example

Community
  • 1
  • 1
Alex Fitzpatrick
  • 643
  • 5
  • 10