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
-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
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.
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.
-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
Create a Dir Context to pointing to the Root DSE or a DN under it
DirContext ctx = InitialDirContext(ldapEnv);
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)))";
Most servlet containers can be configured to authenticate via LDAP, that would be significantly more secure and reliable than rolling your own authentication code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.