我的任务是创建一个.NET Core(C# MVC(应用程序,该应用程序可以通过Active Directory或个人用户帐户进行身份验证。
互联网上有无数关于设置一个或另一个的资源,我已经用它们创建了应用程序。但是有可能两者兼而有之吗?
OAuth似乎允许在.NET Core中开箱即用的多个身份验证路由,但我的猜测是Active Directory并不容易工作,在IIS中配置并使用操作系统进行授权。
如果无法同时做到这两点 - 我有什么选择?我猜我会创建两个单独的项目来做同样的事情,但具有不同的身份验证 - 但维护两个项目似乎不是一个好主意。
提前感谢您的任何建议。
我已经拼凑了一些资源,我决定创建一个简单的自定义身份验证,允许 Active Directory 和数据库中的个人用户帐户。
首先,我将 ASP.NET 标识添加到现有项目中。我使标识接口比链接答案简单得多:
身份配置.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 关于在 ASP.NET 中创建自定义身份验证/授权的回答(再次(,然后我在数据库中创建了一个简单的数据库优先用户和角色表,而不是基于 Identity,并创建了一个用户管理器类:
用户管理器.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
。
身份验证控制器.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();
}
}
这种简单性似乎正是我想要的,而不是携带大量的身份或 ASP.NET 成员资格,而且效果很好。
现在回答我最初的问题 - 我如何也容纳Active Directory用户?
虽然我抽象出并大大简化了我的 USER 和 ROLE 类,但用户将需要大量额外的数据(角色、权限等( - 并且这些数据不会在 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 的其他数据。 此外,由于我们需要在自定义表中指定 Role 和其他数据,因此无论如何都必须创建自定义用户记录。
我的困惑促使我回答,因为不了解在 .NET 中创建自定义身份验证的灵活性,而无需使用他们烘焙的内容(例如在创建新项目时检查"个人用户帐户"选项(。
欢迎其他建议,因为这是我 ASP.NET 知识的范围 - 但我相信这将适用于我的应用程序。我希望这有助于某人的身份验证设置。
您可以使用您想到的方式进行身份验证,也可以将注意力转向选择 IdentityServer4,这是一个功能齐全的身份验证项目,可以满足您的需求。
这是另一个接近您正在寻找的内容的堆栈溢出问题。如果您不熟悉 IS4 的工作原理,您可以在此处根据他们的模板创建一个项目;
dotnet new -i "identityserver4.templates::*"