'How can I use ActiveDirectoryMembershipProvider with ASP.NET Identity?
I'm learning to use .NET Identity. I have to authenticate to Active Directory. For that purpose I am trying to use ActiveDirecotoryMembershipProvider
. I have to:
- Authenticate user/password against Active Directory (AD).
- Check whether user is present in my own database.
I configured it in my web.config
to use ActiveDirectoryMembershipProvider
as the default membership provider. Then I overrode 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. Is there a better way to achieve this?
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 the 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 a user against multiple Providers, I can create a 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.
Solution 1:[1]
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.
Solution 2:[2]
Try it once following step, may be it will helpful you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | Ajay2707 |