我拼凑了一些资源,并决定创建一个简单的自定义身份验证,允许 Active Directory 和我的数据库中的个人用户帐户。
首先,我添加了ASP.NET Identity to my existing project。我使 Identity 接口比链接的答案更简单:
IdentityConfig.cs
public class IdentityConfig
{
public void Configuration(IAppBuilder app)
{
app.CreatePerOwinContext(() => new Entities());
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Authentication/Login"),
});
}
}
根据@Sam 在creating custom authentication/authorization in ASP.NET 上的回答(再次),我在数据库中创建了一个简单的数据库优先用户和角色表,而不是基于身份,并创建了一个用户管理器类:
UserManager.cs
public class UserManager
{
private Entities db = new Entities();
public bool IsValid(string username, string password)
{
// TODO: salt and hash.
return db.USER.Any(u => u.USERNAME == username && u.PASSWORD == password);
}
}
最后,为了完成自定义身份验证,我创建了一个非常简单的身份验证控制器。这将检查用户是否有效,然后创建一个ClaimIdentity。
AuthenticationController.cs
public class AuthenticationController : Controller
{
private Entities db = new Entities();
public ActionResult Login()
{
return View();
}
public ActionResult Logout()
{
HttpContext.GetOwinContext().Authentication.SignOut();
return RedirectToAction("Index", "Home");
}
[HttpPost]
public ActionResult Login(string username, string password)
{
UserManager um = new UserManager();
bool valid = um.IsValid(username, password);
if (valid)
{
// get user role and enditem
USER user = db.USER.Where(u => u.USERNAME == username).First();
string role = db.ROLE.Where(r => r.USERID == user.USERID).FirstOrDefault().ROLENAME;
// create session
Claim usernameClaim = new Claim(ClaimTypes.Name, username);
Claim roleClaim = new Claim(ClaimTypes.Role, role);
ClaimsIdentity identity = new ClaimsIdentity(
new[] { usernameClaim, roleClaim }, DefaultAuthenticationTypes.ApplicationCookie
);
// auth succeed
HttpContext.GetOwinContext().Authentication.SignIn(new AuthenticationProperties { IsPersistent = false }, identity);
return RedirectToAction("Index", "Home");
}
// invalid username or password
ViewBag.error = "Invalid Username";
return View();
}
}
这种简单性似乎正是我想要的,而不是像 Identity 或 ASP.NET 成员那样大容量,而且效果很好。
现在回答我最初的问题 - 我如何也适应 Active Directory 用户?
虽然我抽象出并大大简化了我的 USER 和 ROLE 类,但 USER 将需要大量额外数据(角色、权限等) - 这些数据不会在 Active Directory 中 - 我们需要无论如何创建一个用户。
因此,我只需要validate the username and password in Active Directory!
一个快速配置变量可以改变Login动作中的控制流,然后执行这个:
bool isValid = false;
if (authConfig == "AD") {
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "US"))
{
// validate the credentials
isValid = pc.ValidateCredentials(username, password);
}
} else if (authConfig == "Custom") {
isValid = um.IsValid(username, password);
}
// create claim...
此解决方案是可行的,因为 Active Directory 身份验证的唯一目的是验证其用户 - 不需要来自 AD 的其他数据。此外,由于我们需要在自定义表中指定角色和其他数据,因此无论如何都必须创建自定义用户记录。
促使我回答的困惑是缺乏对在 .NET 中创建自定义身份验证的灵活性的理解,而无需使用它们所包含的内容(例如在创建新项目时检查“个人用户帐户”选项) .
欢迎提出其他建议,因为这是我的 ASP.NET 知识范围 - 但我相信这对我的应用程序有用。我希望这有助于某人的身份验证设置。