2017-04-04 230 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。

相关问题