我有一个ASP.Net应用程序。要求是使用ADFS实现表单身份验证。 如果用户正在域内(与Active Directoris相同的域)访问WebSite,则应执行表单身份验证。 即,使用用户的Windows登录电子邮件ID,我们应该检查用户是否存在于Active Directory中。如果用户存在,则用户可以访问该网站。 如果未根据他/她的电子邮件ID找到用户,则向用户询问他/她的用户名和密码,并选择应在其上搜索用户的两个活动目录之一。 (PN:有两个活动目录。一个默认用于在域中使用。)
如果用户从域外访问网站,则始终向用户询问他/她的用户名和密码,并选择用户所属的两个活动目录中的一个。
因此,有一个URL可以在域中访问网站,另一个可以从域外访问。
我需要帮助来完成这项任务。 该项目位于Dot.Net,使用ASP.Net和C#上的Framework 3.5。
高度赞赏代码解决方案的帮助。
答案 0 :(得分:1)
我做到了这一点。基本思想是您的主要身份验证形式是表单。但是,您使默认登录页面使用Windows身份验证。如果Windows身份验证成功,则创建Forms票证并继续。如果没有,则显示登录页面。
唯一需要注意的是,由于Windows身份验证始终向浏览器发送401响应(对Windows凭据提出质疑),因此非域用户将始终获得一个凭据弹出窗口,他们必须单击“取消”。 / p>
我在我的项目中使用了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中设置它并将调试器指向该位置。
答案 1 :(得分:0)
OOTB解决方案可能适合您。
同时使用ADFS WAP并设置裂脑DNS。
内部用户(在域内)获取ADFS框的DNS。默认为Windows身份验证。 (IWA)
外部用户(域外)获取ADFS WAP框的DNS。默认值为FBA。