我受命创建一个可通过Active Directory或单个用户帐户进行身份验证的.NET Core(C#MVC)应用程序。
关于建立一个或另一个,Internet上有许多资源,我已经用它们创建了应用程序。但是,两者都有可能吗?
.NET Core中似乎OAuth allows multiple authentication routes开箱即用,但是我的猜测是Active Directory不太容易工作,需要在IIS中进行配置并使用操作系统进行授权。
如果不能同时做这两个-我有什么选择?我猜我会创建两个单独的项目,它们执行相同的操作,但是具有不同的身份验证-但是维护两个项目似乎不是一个好主意。
在此先感谢您的任何建议。
答案 0 :(得分:1)
您可以按照自己的想法进行身份验证,也可以将重点放在选择IdentityServer4(一个满足您需求的功能齐全的身份验证项目)上。
此处的another stackoverflow question与您要查找的内容很接近。如果您不了解IS4的工作原理,则可以在此处根据其模板创建项目;
dotnet new -i "identityserver4.templates::*"
答案 1 :(得分:1)
我收集了一些资源,因此决定创建一个简单的自定义身份验证,该身份验证允许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"),
});
}
}
在creating custom authentication/authorization in ASP.NET上@Sam回答(又一次)之后,我在数据库中创建了一个简单的Database-First用户和角色表,而不是基于Identity,并创建了一个用户管理器类:
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知识的程度-但我认为这对我的应用程序有效。我希望这有助于某人的身份验证设置。