2013-05-31 55 views
1

我對C#非常陌生,我正在使用LDAP來驗證用戶的登錄憑證和2)獲取有關用戶的其他信息。我們的LDAP服務器不允許我要求匿名發送一些數據,所以我必須等到我用用戶的完整憑證綁定才能提取數據。然而,即使如此,我還無法獲得像sn和givenName這樣的簡單字段。使用JXplorer我可以看到這些值在匿名連接期間隱藏的位置,但是可以在JXplorer中看到完整的用戶/ SSL /密碼組合。我似乎無法通過我的代碼做同樣的事情。無法在LDAP中訪問sn,givenName

如果我在我的第一個FindOne()之後通過屬性循環,找到了9個屬性(其中沒有哪個是我正在尋找的)。如果我在我的 FindOne()後遍歷屬性,則只有4個可用屬性。這兩個結果似乎都不受PropertiesToAdd.Add(「...」)的影響。

任何建議,將不勝感激。

public string[] Authenticate(string user, string password) 
    { 
     string[] results = new string [2]; 

     //Concatenate serverpath + username + container 
     //I.e. "LDAP://ldap.disney.com:636/CN=donaldDuck,ou=people,dc=la,dc=disney,dc=com" 
     DirectoryEntry de = new DirectoryEntry(_ldapserver + "cn=" + user + "," + _topContainer); 
     //User's password for initial verification 
     de.Password = password; 

     //initate anonymous bind 
     de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer; 
     DirectorySearcher searcher = new DirectorySearcher(de); 
     searcher.SearchScope = System.DirectoryServices.SearchScope.Base; 

     //Search for first record 
     SearchResult result = searcher.FindOne(); 

     //Check results 
     if (result == null) throw new Exception(ERR_NOT_FOUND); 

     de = result.GetDirectoryEntry(); 

     //Return search results 
     //results[0] = (string)de.Properties["mail"].Value; 
     // results[1] = (string)de.Properties["givenName"].Value + " " + (string)de.Properties["sn"].Value; 
     // Distingushed Name of the found account 
     string DN = de.Path.Substring(de.Path.ToUpper().IndexOf("CN=")); 
     // Close search connection 
     de.Close(); 


     // now bind and verify the user's password, 
     de = new DirectoryEntry(_ldapserver + _topContainer); 
     de.Username = DN; 
     de.Password = password; 
     de.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer; 

     //Obtain additional information 
     searcher = new DirectorySearcher(de); 
     searcher.PropertiesToLoad.Add("sn"); 
     searcher.PropertiesToLoad.Add("givenName"); 

     SearchResult r = searcher.FindOne(); 
     de = r.GetDirectoryEntry(); 

     foreach (string property in de.Properties.PropertyNames) 
     { 
      Console.WriteLine("\t{0} : {1} ", property, de.Properties[property][0]); 
     } 

     //End obtain additional information 

     //Validate password 
     Object obj = de.NativeObject; 
     de.Close(); 

     //if we made it here, we successfully authenticated 
     return results; 
    } 

回答

0

如果你在.NET 3.5及以上,你應該看看System.DirectoryServices.AccountManagement(S.DS.AM)命名空間。在這裏閱讀全部內容:

基本上,你可以定義域範圍內,並可以輕鬆地查找用戶和/或組AD:

// set up domain context 
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain)) 
{ 
    // validate given user credentials 
    bool isValid = ctx.ValidateCredentials(user, password); 

    // find a user 
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName"); 

    if(user != null) 
    { 
     string surname = user.Surname; 
     string givenName = user.GivenName; 
    } 
}  

的新的S.DS.AM可以很容易地與AD中的用戶和羣組玩耍!

+0

我確實看到這是一個選項,但我認爲這隻適用於MS AD。這是否會對Unix或Novell LDAP服務器起作用? – Trebor

+0

@ user2023444:對不起 - 沒有 - 這實際上只適用於Active Directory(我認爲您正在使用) - 如果沒有:請指定您正在使用的內容以及您正在使用的內容! –

+1

Marc,抱歉,我不知道LDAP服務器品牌是什麼,我只知道它不是AD。但是,我設法解決了這個問題。看來,如果DirectoryEntry(path)構造函數需要完整的DN作爲綁定搜索中的路徑的一部分,而不僅僅是基礎。有一次,我做到了,它工作正常。感謝您的幫助。 – Trebor