2

我有一個Web應用程序(.NET 3.5),它通過電子郵件向用戶發送通知。爲了做到這一點,我搜索Active Directory來查找每個人的電子郵件。如何使用登錄人員的憑據來搜索Active Directory?

此刻,我硬編碼自己的用戶名和密碼,像這樣以搜索廣告:

Dim entry As New DirectoryEntry("LDAP://companyad", "myUsername", "myPassword", AuthenticationTypes.Secure) 
    Dim srch As New DirectorySearcher(entry) 
    srch.Filter = [String].Format("(&(objectClass=person)(sAMAccountName={0}))", "someOtherUsername") 
    Dim result As SearchResult = srch.FindOne() 

現在,很明顯,這不是很理想,我不希望這些證書硬編碼。我的網絡應用程序使用Windows身份驗證。它還使用模擬(作爲登錄用戶)來訪問文件和SQL Server。是否還有一種方法讓我「模仿」登錄用戶以搜索AD?

編輯1

我想我會更好地解釋爲什麼我選擇了這個答案。問題原來不是多跳問題或kerberos,因爲它似乎已經正確設置了這些。

我最近更改了我的應用程序,只允許通過web.config設置訪問某個組。我以前只允許訪問自己。我設立了這個小組,並加入了它。然後我刪除了硬編碼的憑據,並嘗試在沒有重新啓動計算機的情況下運行該應用程序。

根據我的網絡管理員,我不會在該新組下登錄,直到我重新啓動我的計算機,我認爲是什麼導致我的問題。所以,Preet的答案實際上是最準確的,因爲我需要將LDAP路徑傳遞給DirectoryEntry。

EDIT 2

我還需要註冊一個服務主體名稱。

我跑了這一點:

setspn -A HTTP/[dns name of the site] [machine name] 

我的機器上。

感謝其他人的回答。

回答

0

Dim entry As New DirectoryEntry("LDAP://companyad") 

工作?

+0

不幸的是,沒有。我得到這個異常:「Type:System.Runtime.InteropServices.COMException,mscorlib,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089 消息:發生操作錯誤。」有用,嗯? – Andrew 2010-03-04 05:55:58

+0

檢查事件日誌中的內容。 – 2010-03-04 06:19:58

0

爲什麼不爲此創建一個新用戶?只有搜索權限的用戶。

+0

我想這個選項是我最後的選擇。此外,所有密碼每月都會重置是公司政策,這意味着我必須每月在應用中更改密碼。 – Andrew 2010-03-04 06:03:46

+0

啊!!! :)即使我們有這個政策,但有特例的例外。 – Shoban 2010-03-04 06:19:52

+0

哈哈,是的,如果涉及到這一點,那麼我希望我的老闆能夠靈活地適應它。 – Andrew 2010-03-04 06:22:45

0

我在我的web.config中設置了< identity impersonate =「true」/ >,並將以下代碼添加到我的頁面加載事件處理程序中。它運行良好。你確定你沒有處理多跳的情況嗎?在這種情況下,您的應用程序池帳戶需要配置kerberos身份驗證以支持多人場景中的模擬。更多關於這方面的信息是在這裏:http://support.microsoft.com/kb/329986

Response.Write(User.Identity.Name); 
DirectoryEntry entry = new DirectoryEntry("LDAP://[mydomain.net]"); 
DirectorySearcher srch = new DirectorySearcher(entry); 
srch.Filter = string.Format("(&(objectClass=person)(sAMAccountName={0}))", "[user]"); 
SearchResult result = srch.FindOne(); 
Response.Write(result.Path); 
0

如果你想使用Windows用戶帳戶登錄,作爲對AD的憑證,你必須使用以下方法:

public bool IsExistingUser() { 
    DirectoryEntry de = new DirectoryEntry(Environment.UserDomainName) 
    DirectorySearcher ds = new DirectorySearcher(de) 
    ds.Filter = string.Format("((objectClass=user)(SAMAccountName={0}))", Environment.UserName) 

    try 
     SearchResult sr = ds.FindOne(); 
     if (sr != null && sr.DirectoryEntry.Name.Contains(Environment.UserName)) 
      return true; 
    catch (DirectoryServicesCOMException ex) 
    catch (COMException ex) 
     throw new Exception("Can't find logged in user in AD", ex); 

    return false; 
} 

假設這段代碼編譯並運行,它將驗證您的域控制器是否知道現有的登錄用戶。

模仿不鼓勵,因爲它可以讓你的網絡上傳輸密碼字符串。所以,儘量避免它。

編輯這裏是一個非常有用的廣告鏈接:Howto: (Almost) Everything In Active Directory via C#我覺得這篇文章真棒!