我有一个MVC5应用程序正在使用针对AD的表单身份验证。我希望能够使用Windows身份验证,如果用户已经在他们的计算机上登录到AD,如果没有进入表单身份验证,他们可以输入他们的AD凭据。
在没有编写自定义成员资格类的情况下,是否有相对直接的方法来处理此问题?如果是这样怎么样?任何帮助,将不胜感激。我看过几篇关于不混合身份验证类型的帖子,但我没有使用任何本地身份验证。这一切都是针对AD的。这仍然不受支持吗?
答案 0 :(得分:1)
IIS在技术上不支持(如果这是您正在使用的),但您可以启用表单和Windows身份验证。
在表单身份验证设置的“loginUrl”中使用的任何控制器中(在Web.config中),您可以检查标头以确定用户是否已登录,例如:
鉴于此设置
<forms loginUrl="~/Login">
你可以这样做:
public class LoginController: Controller
{
public ActionResult Index()
{
string windowsUserName = Request.ServerVariables["LOGON_USER"];
if (!string.IsNullOrEmpty(windowsUserName))
{
Regex regex = new Regex(@"(^\w+)\\", RegexOptions.IgnoreCase);
string userName = regex.Replace(windowsUserName, string.Empty);
// validate the user name against ad here
FormsAuthentication.SetAuthCookie(userName, false);
this.RedirectToAction("Index", "Home");
}
else
{
// if the user isn't signed in with AD credentials you can send an
// "unauthorized" http code and the browser (excluding Firefox)
// will try to send credentials (if available).
// you will have to manage staying out of a redirect loop
// many options here: set and check a cookie, session, headers, etc.
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
}
}
}
当我必须为特定应用程序执行此操作时,我还检查了请求主机地址(以确保它与服务器位于同一域中,否则我甚至不打扰:
IPAddress address = null;
if (IPAddress.TryParse(Request.UserHostAddress, out address))
{
if (IPAddress.IsLoopback(address))
{
address = Dns.GetHostAddresses(Dns.GetHostName()).FirstOrDefault(ip => !IPAddress.IsLoopback(ip));
if (address == null)
return View();
}
IPHostEntry entry = Dns.GetHostEntry(address);
bool isPartOfDomain = false;
foreach (IPAddress hostEntryAddress in entry.AddressList)
{
if (String.Equals(address.ToString(), hostEntryAddress.ToString()))
{
string domain = "Your Domain Here"; // or get it from your configuration settings / db / etc
using (PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, domain))
{
string computerName = entry.HostName.Replace("." + domain, string.Empty);
using (ComputerPrincipal computer = ComputerPrincipal.FindByIdentity(domainContext, computerName))
if (computer != null)
{
isPartOfDomain = true;
break;
}
}
}
}
}
我通常会检查域PrincipalContext以验证用户名。
DirectoryEntry entry;
string domain = "Your Domain Here",
userName = "Some User Name";
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain))
{
using (UserPrincipal principal = UserPrincipal.FindByIdentity(context, userName))
{
if (principal != null && (entry = (DirectoryEntry)principal.GetUnderlyingObject()) != null)
{
string userPrincipalName = principal.UserPrincipalName ?? principal.Name;
userPrincipalName = userPrincipalName.Substring(0, (userPrincipalName.Contains("@") ? userPrincipalName.IndexOf("@") : userPrincipalName.IndexOf(" ")));
bool isValid = string.Equals(userName, userPrincipalName);
}
}
}