【问题标题】:Using Both Active Directory Authentication and Individual User Accounts in .NET Core在 .NET Core 中同时使用 Active Directory 身份验证和个人用户帐户
【发布时间】:2018-10-31 07:17:14
【问题描述】:

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

互联网上有无数关于设置其中一个的资源,我已经用它们创建了应用程序。但是有可能两者都做吗?

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

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

提前感谢您的任何建议。

【问题讨论】:

  • 哪个优先?如果用户名既存在于 AD 中又作为个人帐户存在,哪个系统对该用户名具有权威性?
  • @JoelCoehoorn 根据客户的不同,我们将使用 AD 或个人帐户部署它。
  • 你可能想考虑一下提供者模式。为账户安全提供者定义一个接口,然后实现该接口两次,一次用于内部账户,一次用于活动目录。甚至可能是第三次进行单元测试模拟。
  • 这听起来正是我想要的——但我正在努力为 AD 和个人寻找一个好的资源,特别是。这似乎很接近:docs.microsoft.com/en-us/aspnet/core/security/authentication/…

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


【解决方案1】:

您可以按照自己的想法进行身份验证,也可以将注意力转向选择 IdentityServer4,这是一个功能齐全的身份验证项目,可以满足您的需求。

这里是another stackoverflow question,这与您要查找的内容很接近。如果您不熟悉 IS4 的工作原理,您可以在这里根据他们的模板创建一个项目;

dotnet new -i "identityserver4.templates::*"

【讨论】:

  • 感谢@Nicholas 的资源!虽然我不希望使用 3rd 方解决方案,但我会考虑。
  • @chakeda 我喜欢不使用第 3 方解决方案!不用担心,因为 IS4 是一个超级支持的库。当谈到在 .NET Core 上开发新的身份验证服务器时,这几乎是人们首先想到的。
【解决方案2】:

我拼凑了一些资源,并决定创建一个简单的自定义身份验证,允许 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 知识范围 - 但我相信这对我的应用程序有用。我希望这有助于某人的身份验证设置。

【讨论】:

    猜你喜欢
    • 2015-02-20
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多