I am trying to get a person's Email ID as well as his/her manager's email ID. And the following is the code I tried.
DirContext ctx = new InitialDirContext(LDAPDetails());
String[] attrIDs = {"sAMAccountName", "cn", "title", "mailnickname", "mail", "manager", "department", "telephoneNumber"};
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(CN=285263)";
NamingEnumeration<SearchResult> answer = ctx.search("OU=users,DC=cts,DC=com", filter , ctls);
answer = ctx.search("OU=xyz,DC=cts,DC=com", filter , ctls);
while (answer.hasMore()) {
SearchResult sr = (SearchResult) retEnum.next();
Attribute mailAttribute=sr.getAttributes().get("mail");
System.out.println("Team Member's eMail: "+mailAttribute.get()); //Here I am able to get the person's email.
Attribute managerAttribute=sr.getAttributes().get("manager"); // this is just getting the manager's CN value. Not the email ID.
}
Can someone help me get the manager's email ID please? Thanks in advance.
You'll have to lookup the manager(s) to get his (their) email address(es):
DirContext ctx = new InitialDirContext(LDAPDetails());
String[] attrIDs = { "sAMAccountName", "cn", "title", "mailnickname", "mail", "manager", "department", "telephoneNumber" };
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(CN=285263)";
NamingEnumeration<SearchResult> answer = ctx.search("OU=users,DC=cts,DC=com", filter, ctls);
while (answer.hasMore()) {
SearchResult sr = (SearchResult) retEnum.next();
Attribute mailAttribute = sr.getAttributes().get("mail");
System.out.println("Team Member's eMail: " + mailAttribute.get()); // Here I am able to get the person's email.
Attribute managerAttribute = sr.getAttributes().get("manager"); // this is just getting the manager's CN value. Not the email ID.
// now lookup the manger
NamingEnumeration<SearchResult> managerAnswer = ctx.search(managerAttribute.get(), "", ctls);
while (answer.hasMore()) {
SearchResult managerSr = (SearchResult) retEnum.next();
Attribute mailAttribute = sr.getAttributes().get("mail");
System.out.println("Managers eMail: " + mailAttribute.get());
}
}
Here is my approach...
1..Connecto to LDAP
2..Search the user and Get manager name
3.. Search the LDAP with the manager name and object class as user in filter condition.
NamingEnumeration answermanager = context.search(managerAttribute.get().toString(),"(objectClass=user)",searchCtls);
Related
At the same time of providing authentication to the user in LDAP within Microsoft Active Directory, I'm trying to get all groups that specific user belongs to. The following code is in Java.
What I'm doing at the moment is the following:
public static List authenticate(String username, String password) throws Exception {
String LDAPURL = MY_LDAP_URL;
String userBase = MY_USERBASE; //format "dc=***,dc=com"
ArrayList<String> groups = new ArrayList<String>();
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, LDAPURL);
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, username);
environment.put(Context.SECURITY_CREDENTIALS, password);
DirContext ctx =
new InitialDirContext(environment);
SearchControls ctls = new SearchControls();
String[] attributes = {"cn", "memberOf"};
ctls.setReturningAttributes(attributes);
ctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
String searchFilters = "{sAMAccountName="+username+"}";
NamingEnumeration<?> answer = ctx.search(userBase, searchFilters, ctls);
if(answer == null || !answer.hasMore()) {
logger.info("No result found");
}
else {
SearchResult result = (SearchResult) answer.next();
Attributes attrs = result.getAttributes();
Attribute memberAttr = attrs.get("memberOf");
NamingEnumeration e = memberAttr.getAll();
while(e.hasMore()) {
String group = (String) e.next();
groups.add(group);
logger.info(group);
}
}
return groups;
}
I have tried several ways of doing my query, for example:
String searchFilters = "(&(uid="+username+"),(ou=users),(memberOf=*))"
Or
String searchFilters = "(&(objectClass=groupOfNames)(member=cn=" + username + ")(memberOf=*))"
Or
String searchFilters = "(&(userPrincipalName=" + username + ")(memberOf=*))"
In none of the cases any groups were retrieved. In some of the cases the login itself failed as well (in some cases it worked but still no groups returned).
What is the correct way to retrieve the groups?
Although you can bind with "username" and some other attributes, using ANR, ONLY when using Microsoft Active Directory, you will need to obtain the Fully Distinguished Name for the user to perform many LDAP Searches.
Assuming username is the samAccountName, which is always Unique within a AD Forrest, your Authentication should work.
After Authentication you can obtain the DN of the entry and then perform a search for Groups the user is a member.
For all groups the user is a member, including nested groups this will usually work.
(member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))
We have several JNDI Examples in a code repository.
Here is the method which i have used to fetch but nothing is being populated.
public void doSearch() throws NamingException {
String searchFilter = "(&(ou=Example,ou=Examples_ou)(objectClass=person))";
String domain = "DC=mydom,DC=com";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> answer = ctx.search(domain, searchFilter, searchControls);
int ttl = 0;
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
ttl++;
System.out.println(">>>" + sr.getName());
Attributes attrs = sr.getAttributes();
System.out.println(">>>>>>" + attrs.get("samAccountName"));
}
System.out.println("Total results: " + ttl);
}
Your filter is invalid, thus returns no data. In
ctx.search(domain, searchFilter, searchControls);
domain is being passed as the base DN for the search. If you want to restrict your search to users within ou=Example,ou=Examples_ou of dc=example,dc=com, then your search base DN should be "ou=Example,ou=Examples_ou,dc=example,dc=com" and searchFilter would be simply "(&(objectClass=person))"
Please find my code snippet below:
String[] attrIDs = {"title", "Depatrment", "DivisionDescription" };
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> answer = ctx.search(ldapServerSearchBase, FILTER, ctls);
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
String str_title = attrs.get("title").toString();
String str_dept = null;
String str_desc = null;
if(str_title.equals("Professor"))
{
str_dept = attrs.get("Depatrment").toString();
str_desc = attrs.get("DivisionDescription").toString();
}
System.out.println(str_title);
System.out.println(str_dept);
System.out.println(str_desc);
When I run this code, it always displays null when i output str_dept and str_desc. But it does display str_title correctly as "Professor".
Please help me understand what could be going wrong here.
Thanks!
Are you sure that the attributes you're fetching even exists?
str_dept = attrs.get("Depatrment").toString();
str_desc = attrs.get("DivisionDescription").toString();
Firstly, the Depatrment is spelled wrong, and the DivisionDescription most likely does not exists (at least not in the default schematics for most directory services). Might be you need the following attributes?:
DivisionDescription => division
Depatrment => department
However, check that your directory service actually even posess the requested attributes (and that users actually have some values within these attributes).
Although I am sure, if more information were provided, there is a better method to do this, the example below should get you on your way:
String[] attrIDs = {"title", "Depatrment", "DivisionDescription" };
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> answer = ctx.search(ldapServerSearchBase, filter, ctls);
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
String str_title=null;
String str_dept = null;
String str_desc = null;
if( attrs.get("title")!=null)
{
str_title = attrs.get("title").toString();
System.out.println(str_title);
if(str_title.equals("Professor"))
{
str_dept = attrs.get("Depatrment").toString();
str_desc = attrs.get("DivisionDescription").toString();
System.out.println(str_dept);
System.out.println(str_desc);
}
}
-jim
I want to get user DN with the username provided.
What I think is that I want to retrieve all the user data and compare with the username.
And now, I have added objectclass in my search filter and I have no idea why is the data is not retrieving.
Here are the codes that I currently have.
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,ou=sa,o=system");
env.put(Context.SECURITY_CREDENTIALS, "P#ssw0rd");
try{
DirContext context = new InitialDirContext(env);
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration result = context.search("", "(objectclass=Person)", constraints);
while(result.hasMore())
{
SearchResult searchResult = (SearchResult) result.next();
Attributes attrs = searchResult.getAttributes();
request.setEmail(attrs.get("mail").toString());
request.setPhoneNumber(attrs.get("personalMobile").toString());
Attribute ldapattr = attrs.get("photo");
if(ldapattr != null){
byte[] photo = (byte[])ldapattr.get();
request.setPhoto(photo);
}
}
}catch(Exception e){
System.out.println("can't initialized");
}
list.add(request);
//Specific URL of LDAP with the host and :port
return list;
}
Provide a base DN to search. e.g. ou=users below and add username to filter for faster search
Don't get all the user data as you are unnecessarily increasing network traffic and doing additional computational work on the client.
LDAP server excels at this kind of searching. CN is indexed by default but givenName may not be indexed; so you might want to add an index for this attribute.
NamingEnumeration result = context.search("ou=users",
"(&(objectClass=person)(sAMAccountName=" + userId + "))", constraints);
If you have givenName
NamingEnumeration result = context.search("ou=users",
"(&(objectClass=person)(givenName=" + givenName + "))", constraints);
I am currently maintaining some library scanning software at a company, and I am at a coop for (I am in high school). I have to be able to pass an employeeID value from the scanner to the LDAP lookup to return a "CN" value.
Unfortunately, I am not getting any results returned in the Java program. I am able to search using the Active Directory program in Windows, but it takes 6 to 10 seconds to display any results from employeeID. I attempted to solve this issue by using a very large timeout limit on the query, but I think I must be doing something wrong.
Anyone with database experience have any ideas?
try
{
System.out.println("Début du test Active Directory");
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(INSERT CREDENTIALS HERE);
env.put("com.sun.jndi.ldap.timeout", "80000");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_PROTOCOL, "simple");
ldapContext = new InitialDirContext(env);
// Create the search controls
SearchControls searchCtls = new SearchControls();
//Specify the attributes to return
String returnedAtts[]={"cn","givenName", "samAccountName"};
searchCtls.setReturningAttributes(returnedAtts);
//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//specify the LDAP search filter
id = "********";
String searchFilter = "(&(employeeID="+id+"))";
//Specify the Base for the search
String searchBase = "dc=ericsson,dc=se";
//initialize counter to total the results
SearchResult sr = null;
int totalResults = 0;
NamingEnumeration<SearchResult> answer = ldapContext.search(searchBase, searchFilter, searchCtls);
// Search for objects using the filter
while (totalResults == 0){
answer = ldapContext.search(searchBase, searchFilter, searchCtls);
System.out.println("Total results: " + totalResults);
while (answer.hasMoreElements())
{
sr = answer.next();
System.out.println(sr);
totalResults++;
System.out.println(">>>" + sr.getName());
Attributes attrs = sr.getAttributes();
cn = (">>>>>>>>>" + attrs.get("cn"));
signum = cn.substring(13,20);
System.out.println("Total results: " + totalResults);
}
}
//Loop through the search results
You need to ensure that the employeeID attribute is indexed.
You should also qualify your filter further. I would add at least an objectClass filter, set to whatever object class you're using for people.