How to use ActiveDirectoryMembershipProvider with

2019-04-18 07:07发布

I am trying to learn how to use ASP.Net Identity. My scenario is that I have to authenticate against Active Directory. For that purpose I am trying to use ActiveDirecotoryMembershipProvider. What I have to do is -

  1. Authenticate user/password against Active Directory.
  2. Check whether user is present in my own database.

The way I did it is I configured in my web.config to use ActiveDirectoryMembershipProvider as default membership provider. Then I override PasswordSignInAsync method in my ApplicationSignInManager class (which inherits SignInManager) as follows -

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

This seems to work. But I think it's not the right way to do it. Can anyone suggest any better way to achieve this?

UPDATE

Here is how I called the above mentioned

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

According to the answers I got, I should not call Membership Validate method inside PasswordSignInAsync. I agree with that. In fact, I think overriding the method is wrong as well.

It was also suggested that I use UserLogins where I would give my AD an provider ID. But the only way I can think of using this is as follows -

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

So, if I want to authenticate an user against multiple Providers I can create provider key for each of them and assign those provider keys to the users. And this code will validate the user against them. But where should I put this code? What convention should I follow?

I am not keen on coding the AD validation myself because I think ActiveDirectoryMembershipProvider can do a better job than my own code. Also for both cases I have to add reference to System.DirectoryServices anyway.

2条回答
一纸荒年 Trace。
2楼-- · 2019-04-18 07:34

You don't want to mix MembershipProviders with identity. What you most likely want to do, is treat logging into ActiveDirectory similar to how identity treats other external logins (like google/facebook).

This basically boils down to storing the AD username as a login:

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

If you only login via AD, then you could indeed override PasswordSignIn to explicitly validate against AD

Otherwise, you'd want this in only the specific login flow for AD, preserving the existing local password/social login functionality.

查看更多
戒情不戒烟
3楼-- · 2019-04-18 07:56

Try it once following step, may be it will helpful you.

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

查看更多
登录 后发表回答