如何将ActiveDirectoryMembershipProvider与ASP.Net Identity一起使用?

时间:2015-04-27 06:18:30

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

我正在尝试学习如何使用ASP.Net Identity。我的方案是我必须针对Active Directory进行身份验证。为此我试图使用ActiveDirecotoryMembershipProvider。我要做的是 -

  1. 针对Active Directory验证用户/密码。
  2. 检查用户是否在我自己的数据库中。
  3. 我这样做是因为我在web.config中配置使用ActiveDirectoryMembershipProvider作为默认会员提供商。然后我在PasswordSignInAsync类(继承ApplicationSignInManager)中覆盖SignInManager方法,如下所示 -

    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();
    }
    

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

    还有人建议我使用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;
    }
    

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

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

2 个答案:

答案 0 :(得分:5)

您不希望将MembershipProviders与身份混合。您最有可能想要做的是,记录到ActiveDirectory,类似于身份如何处理其他外部登录(如google / facebook)。

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

userManager.AddLogin(<userId>, new UserLoginInfo("ActiveDirectory", "<ADUserName>")

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

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

答案 1 :(得分:0)

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

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