2015-07-09 2 views
0

Я написал приложение Java для получения выбранных атрибутов учетной записи пользователя AD, чтобы попытаться сопоставить записи сотрудников HR персонала с AD. Все работает отлично, за исключением того, что атрибут «accountExpires» всегда возвращает null в моем коде. Когда я проверяю образец одних и тех же учетных записей пользователей, используя средство просмотра Apache LDAP (плагин Eclipse), я могу видеть дату/время и длительное значение.Проблема с LDAP Active Directory вождения меня гайки

Вот мой код, который работает для всего, кроме получения атрибута accountExpires. упаковка com.acne.LDAPRealmTest;

import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileWriter; 
import java.util.Hashtable; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.concurrent.TimeUnit; 
import javax.naming.NameClassPair; 
import javax.naming.Context; 
import javax.naming.NamingEnumeration; 
import javax.naming.NamingException; 
import javax.naming.directory.BasicAttribute; 
import javax.naming.directory.BasicAttributes; 
import javax.naming.directory.Attributes; 
import javax.naming.directory.Attribute; 
import javax.naming.directory.DirContext; 
import javax.naming.directory.InitialDirContext; 
import javax.naming.directory.SearchControls; 
import javax.naming.directory.SearchResult; 
import javax.naming.ldap.InitialLdapContext; 
import javax.naming.ldap.LdapContext; 

public class LDAPCtxTest { 
    DirContext ctx = null; 
    StringBuffer sb = new StringBuffer(); 
    int counter=0; 
    SearchControls controls; 
    private final static long DIFF_NET_JAVA_FOR_DATE_AND_TIMES = 11644473600000L; 

    public LDAPCtxTest() { 
     try { 
      System.out.println("Active Directory search test"); 
      Hashtable<String, String> env = new Hashtable<String, String>(); 

     /* Begin by defining the environment properties and getting the InitialDirContext class object initialized. 
      */ 

     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
     env.put(Context.PROVIDER_URL, "connection_string"); 
     env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
     env.put(Context.SECURITY_PRINCIPAL, "CN=LDAP_USER,OU=Service Accounts,OU=System Administration,DC=acne,DC=com,DC=au"); 
     env.put(Context.SECURITY_CREDENTIALS, "test01"); 
     env.put(Context.REFERRAL, "follow"); 

     ctx = new InitialDirContext(env); 
      // Create the search controls   
      controls = new SearchControls(); 

      //Specify the attributes to return 
      String returnedAtts[]={"sn","name", "accountExpires", "sAMAccountName", "department","telephoneNumber","userAccountControl","cn","pwdLastSet","accountExpires","objectcategory"}; 
      controls.setReturningAttributes(returnedAtts); 

      //Specify the search scope 
      controls.setSearchScope(SearchControls.SUBTREE_SCOPE); 

      //String searchFilter = "(&(objectClass=user)(userAccountControl=512))"; 
      String searchFilter = "(&(objectCategory=person)(objectClass=user)(userAccountControl=512))"; 
      //Specify the Base for the search 
      String searchBase = "DC=acne,DC=com,DC=xx"; //this doesn't seem to work so replaced with empty string which is ok 
      //initialize counter to total the results 
      //controls.setCountLimit(100); // limits the search result to 200 

      File outFile = new File("C:\\temp\\", "ldaptest.txt"); 
      BufferedWriter bw = new BufferedWriter(new FileWriter(outFile)); 
      bw.write("Counter,sAMAccountName,userAccountControl,name,AccountExpiry\n"); 
      NamingEnumeration<SearchResult> answer = ctx.search("", searchFilter, controls); 
      //Loop through the search results 
      while (answer.hasMoreElements()) 
      { 
       SearchResult sr = (SearchResult)answer.next(); 
       Attributes attrs = sr.getAttributes(); 
       Attribute attrAccountControl = attrs.get("userAccountControl"); 
       Attribute attrName = attrs.get("name"); 
       Attribute attrAccountExpire = attrs.get("accountExpires"); 
       Attribute attrSAMAccount = attrs.get("sAMAccountName"); 

       counter++; 
       sb.append(counter+","+attrSAMAccount.get(0)+","+attrAccountControl.get(0)+","+attrName.get(0)+ ","+attrAccountExpire+"\n"); 
       System.out.println(counter + " " + attrSAMAccount.get(0) + "..." + attrAccountControl.get(0)); 
      } 
      bw.write(sb.toString()); 
      bw.close(); 
      System.out.println("The End"); 
      ctx.close(); 
      System.out.println("LDAP connected ok"); 
    } catch (NamingException ne) { 
     System.out.println("LDAP connect FAILED"); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    }  
} 

private Date getDateTimeFrom(String adDateTimeStr) { 
    long adDateTime = Long.parseLong(adDateTimeStr); 
    long milliseconds = (adDateTime/10000) - DIFF_NET_JAVA_FOR_DATE_AND_TIMES; 
    //long milliseconds = (adDateTime/10000) - DIFF_NET_JAVA_FOR_DATE_AND_TIMES; 
    Date dateVal = new Date(milliseconds); 
    return dateVal; 
} 


public static void main(String[] args) { 
    new LDAPCtxTest(); 
} 

}

Я посмотрел на различных потоков, касающихся запроса LDAP, особенно относящиеся к accountExpires и посмотрел на сайте Microsoft, которые перечислены атрибуты LDAP. Похоже, что нет ничего неправильного в названии атрибута, которое я указал выше, и я не нашел никого другого с подобными проблемами. Я не уверен, что еще может быть проблемой.

+0

Поскольку «accountExpires» является операционным атрибутом Active Directory, я пробовал следующее без успеха: Строка, возвращеннаяAtts [] = {"*", "+"}; – Joy

+0

Примечание: Мне удалось получить атрибут после переключения с LDAPS на протокол LDAP. – Joy

ответ

0

Ответ: Атрибут «accountExpires» был доступен после того, как я переключился с LDAPS на LDAP. В идеале я предпочитаю, по соображениям безопасности, подключаться через LDAPS, но администрирование Active Directory не является моей областью, и я разрешу этому решению сидеть с гуру AD.

Также обратите внимание, что мне удалось получить доступ к этому (оперативному) атрибуту, не добавляя его в returnAttrs «+».

+0

Чтобы завершить этот разговор, я хотел бы сказать, что для LDAP и LDAPS, возможно, была настроена фильтрация брандмауэра или порта, что объясняет различные ответы на запросы. Только это я ожидал бы более жесткого контроля над небезопасным портом, чего не было. – Joy