在.NET Core中同时使用Active Directory身份验证和单个用户帐户

时间:2018-09-25 23:41:24

标签: c# .net active-directory asp.net-identity

我受命创建一个可通过Active Directory或单个用户帐户进行身份验证的.NET Core(C#MVC)应用程序。

关于建立一个或另一个,Internet上有许多资源,我已经用它们创建了应用程序。但是,两者都有可能吗?

.NET Core中似乎OAuth allows multiple authentication routes开箱即用,但是我的猜测是Active Directory不太容易工作,需要在IIS中进行配置并使用操作系统进行授权。

如果不能同时做这两个-我有什么选择?我猜我会创建两个单独的项目,它们执行相同的操作,但是具有不同的身份验证-但是维护两个项目似乎不是一个好主意。

在此先感谢您的任何建议。

2 个答案:

答案 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知识的程度-但我认为这对我的应用程序有效。我希望这有助于某人的身份验证设置。