2017-04-04 229 views
0

我有一個ASP.Net應用程序。要求是使用ADFS實現表單身份驗證。 如果用戶正在從域內(與Active Directoris相同的域)訪問WebSite,則應執行表單身份驗證。 即使用用戶的Windows登錄電子郵件ID,我們應該檢查用戶是否存在於Active Directory中。如果用戶存在,則該用戶可訪問該網站。 如果根據他/她的電子郵件ID找不到用戶,則向用戶詢問他/她的用戶名和密碼,並選擇用戶應該在其上搜索的兩個活動目錄中的一個。 (PN:有兩個活動目錄,一個默認值用於在域中使用)使用窗體身份驗證和Windows身份驗證的Active Directory

如果用戶從域外訪問本網站,那麼用戶總是被問到他/她的用戶名和密碼,並選擇用戶所屬的兩個Active Directory中的一個。

因此,有一個URL用於從域中訪問網站,另一個用於從域外訪問網站。

我需要幫助來完成這項任務。 該項目在Dot.Net中,使用ASP.Net和C#上的Framework 3.5。

幫助與代碼解決方案高度讚賞。

+0

請告訴我們您的代碼 –

回答

0

我已經這樣做了。基本思想是你的主要認證形式是Forms。但是,您使默認登錄頁面使用Windows身份驗證。如果Windows身份驗證成功,則創建「表單」工單並繼續。如果不是,則顯示登錄頁面。

唯一需要注意的是,由於Windows身份驗證始終向瀏覽器發送401響應(對Windows憑據進行挑戰),因此非域用戶將始終獲得憑據彈出窗口,他們必須單擊「取消」。

我在我的項目中使用了MVC。我的Windows登錄頁面是/Login/Windows,我的手動登錄頁面是/Login

這裏是我的web.config的相關領域:

<system.web> 
    <authentication mode="Forms"> 
    <forms loginUrl="~/Login/Windows" defaultUrl="~/" name=".MVCFORMSAUTH" protection="All" timeout="2880" slidingExpiration="true" /> 
    </authentication> 
<system.web> 

<location path="Login"> 
    <system.web> 
    <authorization> 
     <allow users="?" /> 
     <allow users="*" /> 
    </authorization> 
    </system.web> 
</location> 
<location path="Login/Windows"> 
    <system.webServer> 
    <security> 
     <authentication> 
     <windowsAuthentication enabled="true" /> 
     <anonymousAuthentication enabled="false" /> 
     </authentication> 
    </security> 
    <httpErrors errorMode="Detailed" /> 
    </system.webServer> 
    <system.web> 
    <authorization> 
     <allow users="?" /> 
    </authorization> 
    </system.web> 
</location> 

這裏是我的LoginController:

[RoutePrefix("Login")] 
public class LoginController : Controller { 

    [Route("")] 
    public ActionResult Login() { 
     //Clear previous credentials 
     if (Request.IsAuthenticated) { 
      FormsAuthentication.SignOut(); 
      Session.RemoveAll(); 
      Session.Clear(); 
      Session.Abandon(); 
     } 
     return View(); 
    } 

    [Route("")] 
    [HttpPost] 
    public ActionResult TryLogin(string username, string password) { 
     //Verify username and password however you need to 

     FormsAuthentication.RedirectFromLoginPage(username, true); 
     return null; 
    } 

    [Route("Windows")] 
    public ActionResult Windows() { 
     var principal = Thread.CurrentPrincipal; 
     if (principal == null || !principal.Identity.IsAuthenticated) { 
      //Windows authentication failed 
      return Redirect(Url.Action("Login", "Login") + "?" + Request.QueryString); 
     } 

     //User is validated, so let's set the authentication cookie 
     FormsAuthentication.RedirectFromLoginPage(principal.Identity.Name, true); 
     return null; 
    } 
} 

你登錄查看將只是一個正常的用戶名/密碼形式,做了POST登錄。

在這一點上,你有一個/Login頁面,人們可以手動去登錄。您還有一個/Login/Windows頁面,該頁面是人們自動重定向到的默認登錄頁面。但是,如果Windows登錄失敗,它將顯示一個通用的401錯誤頁面。

使這種無縫的關鍵是使用您的登錄視圖作爲您的自定義401錯誤頁面。我通過使用ViewRenderer class written by Rick Strahl劫持Application_EndRequest中的響應內容來做到這一點。

的Global.asax.cs:

protected void Application_EndRequest(object sender, EventArgs e) { 
    if (Response.StatusCode != 401 || !Request.Url.ToString().Contains("Login/Windows")) return; 

    //If Windows authentication failed, inject the forms login page as the response content 
    Response.ClearContent(); 
    var r = new ViewRenderer(); 
    Response.Write(r.RenderViewToString("~/Views/Login/Login.cshtml")); 
} 

另一個需要注意的,我發現的是,這並不在IIS Express中(雖然它是一個或兩個版本,因爲我上次嘗試)。我有它在IIS中設置並指向調試器。

+0

謝謝。 你在理解我的要求方面絕對正確。 但是由於我對MVC不甚瞭解,請給我一些ASP.Net C#中的代碼。 我的意思是在哪裏指定AD路徑? 如何使用Windows登錄用戶的電子郵件獲取用戶的詳細信息? 然後我如何使用這些細節並允許用戶訪問網站。我相信有一種叫做令牌的東西。 – Ajinx

+0

MVC是ASP.NET的一部分,我已經展示的代碼已經在C#中:)當Windows身份驗證成功時,用戶的信息在'Thread.CurrentPrincipal'中可用,該代碼在我的代碼示例中使用。 Forms身份驗證令牌允許訪問,它使用'FormsAuthentication.RedirectFromLoginPage'創建。 –

0

有一個OOTB解決方案可能適合你。

使用ADFS WAP以及設置裂腦DNS。

內部用戶(在域內)獲取ADFS框的DNS。默認值是Windows驗證。 (IWA)

外部用戶(域外)獲取ADFS WAP框的DNS。默認是FBA。

相關問題