2010-10-26 10 views
18

我如何能實現在ASP.NET MVC應用程序如下:如何在ASP.NET MVC中使用回退來支持NTLM身份驗證?

  1. 用戶打開內部網站
  2. 如果NTLM身份驗證也沒有制定出
  3. 用戶被悄悄如果可能的話驗證,顯示登錄表單用戶
  4. 用戶指示登錄密碼並選擇域從
  5. 用戶正在使用AD
在代碼驗證預定義域列表210

我知道如何實現4和5,但找不到關於如何結合NTLM和窗體的信息。 因此NTLM本地登錄/密碼對話框從不顯示 - 透明身份驗證或外觀漂亮的登錄頁面。

應該如何工作? 應該詢問用戶名和密碼嗎? 可以使用她當前的憑證(域用戶名)而不要求輸入登錄名和密碼?

更新這些,調查同樣的問題:

當我問這個,我不能完全理解NTLM身份驗證的內部工作原理。 這裏需要了解的重要一點是,如果用戶的瀏覽器不能正確支持NTLM,或者用戶禁用了NTLM支持,服務器將永遠無法獲得解決此問題的機會。

如何Windows身份驗證工作:

  1. 客戶端發送一個普通的HTTP請求到服務器
  2. 服務器,HTTP狀態爲401和指示NTLM身份驗證必須用於接入資源
  3. 客戶端發送NTLM響應類型1消息
  4. 服務器以帶有質詢的NTLM類型2消息進行響應
  5. 客戶端發送類型3消息以迴應質詢
  6. 服務器響應與實際內容請

正如你看到的,瀏覽器不支持NTLM不會轉到步驟(3),而不是生成的用戶將顯示IIS錯誤401頁。

如果用戶沒有憑據,取消NTLM身份驗證彈出對話框窗口瀏覽器將不會繼續(3)。

所以我們沒有機會自動將用戶重定向到自定義登錄頁面。

這裏唯一的選擇是有一個「網關」頁面,我們決定用戶是否應該支持NTLM,如果是,則重定向到受NTLM保護的主頁。

如果沒有,則顯示登錄表單並允許通過手動輸入登錄名和密碼進行身份驗證。

通常通過匹配IP範圍或通過檢查預定義的IP表來決定用戶的IP地址和/或主機名。

+0

HTTP提供的鏈接://計算器。 com/questions/492977/anonymous-access-and-ntlm-authentication-in-iis – 2010-10-26 20:59:14

回答

8

本文可能會讓你指出正確的方向。基本上你有兩個應用程序在同一主機名下的兩個虛擬目錄中。一個應用使用表單身份驗證,一個使用Windows。使用Windows身份驗證的身份驗證會創建一個有效的表單身份驗證Cookie並重定向到第二個虛擬目錄。

ASP.NET Mixed Mode Authentication

0

你不能NTLM和FormsAuthentication在同一個ASP.NET應用程序。您將需要兩個不同的應用程序在不同的虛擬目錄中

+6

不完全正確 - 您無法配置(使用web.config)應用程序以同時支持NTLM和Forms身份驗證,但沒有理由爲什麼您不能創建一個自定義驗證模塊來處理它。 – Keith 2011-01-18 10:07:08

2

我在生產這個確切的設置,設置我的門戶中使用FormsAuth,寫一個函數,它的訪問者IP查找了在該IP/PC登錄的用戶帳戶。使用我找到的名稱(例如,DOMAIN\user),我驗證該域名與我的域名相匹配,並且使用Membership.GetUser(<user>)的用戶名/帳戶在我的FormsAth提供程序中有效。如果此通話返回匹配項,並且用戶IsApproved我爲用戶創建了一個Cookie。我有400多人在網絡上,這是完美的,唯一仍然登錄的計算機是(1.用戶在我的門戶中沒有帳戶,2.幾個MAC/Linux用戶,3.沒有在網絡上啓動的移動用戶並讓組策略啓用他們的防火牆)。

漁獲該解決方案是,它需要模擬域管理員帳戶查詢用戶的PC,並且使用的非託管代碼的netapi32.dll

這裏是我使用的代碼(爲簡潔起見,未提供外部函數調用)。我試圖簡化這一點,因爲有很多外部電話。

string account = String.Empty; 
string domain = String.Empty; 
string user = String.Empty; 


ImpersonateUser iu = new ImpersonateUser(); //Helper that Enabled Impersonation 
if (iu.impersonateValidUser(StringHelper.GetAppSetting("DomainAccount"), StringHelper.GetAppSetting("DomainName"), StringHelper.GetEncryptedAppSetting("DomainAccountPassword"))) 
{ 
    NetWorkstationUserEnum nws = new NetWorkstationUserEnum(); //Wrapper for netapi32.dll (Tested on Vista, XP, Win2K, Win2K3, Win2K8) 
    string host = nws.DNSLookup(Request.UserHostAddress); // netapi32.dll requires a host name, not an IP address 

    string[] users = nws.ScanHost(host); // Gets the users/accounts logged in 

    if (nws.ScanHost(host).Length > 0) 
    { 
     string workstationaccount = string.Empty; 

     if (host.IndexOf('.') == -1) // Pick which account to use, I have 99.9% success with this logic (only time doesn't work is when you run a interactive process as a admin e.g. Run As <process>). 
     { 
      workstationaccount = String.Format("{0}\\{1}$",StringHelper.GetAppSetting("DomainName"), host).ToUpper(); 
     } 
     else 
     { 
      workstationaccount = String.Format("{0}\\{1}$", StringHelper.GetAppSetting("DomainName"), host.Substring(0, host.IndexOf('.'))).ToUpperInvariant(); 
     } 

     account = users[users.Length - 1].Equals(workstationaccount) ? users[0] : users[users.Length - 1]; 

     domain = account.Substring(0, account.IndexOf("\\")); 
     user = account.Substring(account.IndexOf("\\") + 1, 
           account.Length - account.IndexOf("\\") - 1); 
    } 

    iu.undoImpersonation(); // Disable Impersonation 
} 

現在使用我們在第一個函數/過程抓起帳戶,我們現在嘗試驗證,並決定是否要顯示的登錄或自動登錄用戶。

MembershipUser membershipUser = Membership.GetUser(user); 

if (membershipUser != null && membershipUser.IsApproved) 
{ 
    string userRoles = string.Empty; // Get all their roles 
    FormsAuthenticationUtil.RedirectFromLoginPage(user, userRoles, true); // Create FormsAuthTicket + Cookie + 
} 

我寫了一篇博客文章中針對此很久以前,這裏是包裝的的netapi32.dll和我的模擬幫手,我在後Source Code Download

+1

感謝您的詳細回覆,我沒有將它標記爲答案,因爲我覺得它可能有安全問題,總體上有'黑客'的感覺:-) – 2010-10-27 20:24:46

+1

它肯定是一個黑客.. – Zachary 2010-10-27 20:28:58