【问题标题】:How can I use ActiveDirectoryMembershipProvider with ASP.NET Identity?如何将 ActiveDirectoryMembershipProvider 与 ASP.NET 标识一起使用?
【发布时间】:2022-04-28 16:38:32
【问题描述】:

我正在学习使用 .NET Identity。我必须对 Active Directory 进行身份验证。为此,我正在尝试使用ActiveDirecotoryMembershipProvider。我必须:

  1. 根据Active Directory (AD) 验证用户/密码。
  2. 检查用户是否存在于我自己的数据库中。

我在web.config 中将其配置为使用ActiveDirectoryMembershipProvider 作为默认会员提供程序。然后我在我的ApplicationSignInManager 类(继承SignInManager)中覆盖了PasswordSignInAsync 方法,如下所示-

public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
    var adok = Membership.Provider.ValidateUser(userName, password);
    if (adok)
    {
        var user = UserManager.FindByName(userName);
        if (user == null)
            return Task.FromResult<SignInStatus>(SignInStatus.Failure);
        else
        {
            base.SignInAsync(user, isPersistent, shouldLockout);
            return Task.FromResult<SignInStatus>(SignInStatus.Success);
        }
    }
    else
        return Task.FromResult<SignInStatus>(SignInStatus.Failure);
}

这似乎有效。但我认为这不是正确的做法。有没有更好的方法来实现这一点?

我是这样称呼上面的:

var result = await SignInManager.PasswordSignInAsync(username, password, isPersistent: false, shouldLockout: false);
switch (result)
{
    case SignInStatus.Success:
        return RedirectToAction("Index", "Home");
    case SignInStatus.LockedOut:
        return View("Lockout");
    case SignInStatus.Failure:
    default:
        ModelState.AddModelError("", "Invalid login attempt.");
        return View();
}

根据我得到的答案,我不应该在PasswordSignInAsync 中调用Membership Validate 方法。我同意这一点。事实上,我认为重写方法也是错误的。

还有人建议我使用UserLogins 为我的AD 提供一个提供者ID。但我能想到的唯一方法如下 -

IList<UserLoginInfo> loginInfos = await SignInManager.UserManager.GetLoginsAsync(username);
var valid = false;
foreach(var info in loginInfos)
{
    valid = Membership.Providers[info.ProviderKey].ValidateUser(username, password);
    if (valid)
        break;
}

因此,如果我想针对多个 Providers 对用户进行身份验证,我可以为它们中的每一个创建一个提供程序密钥并将这些提供程序密钥分配给用户。这段代码将针对他们验证用户。但是我应该把这段代码放在哪里?我应该遵循什么约定?

我并不热衷于自己编写 AD 验证代码,因为我认为 ActiveDirectoryMembershipProvider 可以比我自己的代码做得更好。同样对于这两种情况,无论如何我都必须添加对System.DirectoryServices 的引用。

【问题讨论】:

  • 不要只是投反对票,请发表评论,以便我了解您投反对票的原因。
  • 我认为您可能被否决了,因为您的帖子似乎没有明显的问题。你有有效的代码,但想要其他途径的建议。这将更适合网站的代码审查部分:codereview.stackexchange.com
  • 为什么?我已经清楚地说明了我想要的问题。我可能有有效的代码,但这并不意味着它是正确的。
  • @ozhug,我见过这个。它使用 Windows 身份验证。但正如我在问题中提到的那样,我需要两个级别的表单身份验证。

标签: c# asp.net asp.net-membership asp.net-identity asp.net-identity-2


【解决方案1】:

您不想将 MembershipProviders 与身份混为一谈。您最可能想要做的是将登录 ActiveDirectory 与身份处理其他外部登录(如 google/facebook)的方式类似。

这基本上归结为将 AD 用户名存储为登录名:

userManager.AddLogin(&lt;userId&gt;, new UserLoginInfo("ActiveDirectory", "&lt;ADUserName&gt;")

如果您只通过 AD 登录,那么您确实可以将 PasswordSignIn 覆盖为显式validate against AD

否则,您只希望在 AD 的特定登录流程中使用此功能,保留现有的本地密码/社交登录功能。

【讨论】:

  • 我不确定如何将 Active Directory 配置为外部登录。你能详细说明一下吗?
  • 当创建用户或现有用户想要链接 AD 登录时,您需要在应用程序 UI 流程中公开它。这就是你调用上面的 AddLogin 代码的时候。
  • 没有什么神奇的配置,你只需要在你的应用程序中为 AD 选择一个 providerID 常量。外部登录表已经通过身份设置,您只需要使用该功能即可。
  • 我没有使用内置数据库或 EF。使用的数据库是自定义的。所以基本上我是从头开始实施它。上面提到的代码放在哪里?
  • 这是通常进入控制器/页面(应用程序代码)的代码,而不是身份代码
【解决方案2】:

按照以下步骤尝试一次,可能会对您有所帮助。

https://msdn.microsoft.com/en-us/library/ff650307.aspx

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多