2011-03-30 77 views
3

我想根據提供的用戶名和密碼驗證本地用戶。我碰到這個線程:Validate a username and password against Active Directory?從網絡驗證本地用戶

這是我如何驗證用戶:

PrincipalContext pc = new PrincipalContext(ContextType.Machine); 
bool isValid = pc.ValidateCredentials(user, pass); 

它的工作原理,只要我在網絡上,但如果我斷開我的電腦給我:

未找到網絡路徑。

我所要做的就是在本地機器上進行驗證,這可能是網絡的一部分,也可能不是網絡的一部分。

編輯:UserPrincipal.FindByIdentity似乎仍然工作沒有廣告,它是給我麻煩的pc.ValidateCredentials。

回答

2

你或許應該看看這個鏈接:How to validate domain credentials?

似乎使用的LogonUser Win32 API函數是唯一的選擇,如果你要能夠完成,即使您的驗證時,AD不在線。但是,並非沒有嚴重的缺點(如線程所示)。您需要用執行您的應用程序的帳戶擁有很多權限。

+0

我改變了鏈接。鏈接的問題包含對主題的深入討論 – 2011-03-30 21:31:06

2

正如您所指出的,System.DirectoryServices名稱空間在斷開連接的上下文中不是非常有用 - 您需要與LSA而不是Active Directory父節點通信。

我不知道官方.Net API對應於advapi32.LogonUser,但您可以調用它來驗證本地緩存登錄。如果機器具有網絡訪問權限,但無法看到域控制器,但可能需要一段時間才能返回。

如果您想通過P/Invoke調用該函數,該函數有一個declaration on pinvoke.net。 (我還沒讀過它,雖然,我發現簽名上pinvoke.net質量變化很大。)

1

一個可能的解決辦法醜 -

使用ValidateCredentials()與ContextType.Machine會經常檢查首先是針對本地系統的證書。如果在本地找不到證書,它只會執行網絡活動。如果拋出並安全地忽略它,你可以捕獲PrincipalOperationException,知道如果方法得到了這麼多的憑據是無效的。

+0

我只想在本地檢查它,問題是如果沒有活動目錄(網絡電纜斷開連接),似乎沒有達到那麼遠。 – Serge 2011-03-30 22:36:26

0
bool valid = false; 
using (PrincipalContext checkpass = new PrincipalContext(ContextType.Machine)) //checks local machine first 
{ 
    try // you need to use try catch when you only have local user 
    { 
     valid = checkpass.ValidateCredentials(user, password); 
    } 
    catch (Exception ex) { valid = true; } 
    if (valid) 
    { 
     // returns ok 
    } 
    else 
    { 
     // returns false 
    }