6
\$\begingroup\$

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 of achieving this?

\$\endgroup\$
2
  • \$\begingroup\$ @th1redy3 can i get the sample for this. i am also implementing active directory authentication plus own database authentication \$\endgroup\$
    – SivaRajini
    Apr 19, 2016 at 13:36
  • \$\begingroup\$ @SivaRajini i couldn't find the sample code. i'll keep looking. meanwhile you can check this, same question i asked at SO which have a bit more info. \$\endgroup\$
    – th1rdey3
    Apr 20, 2016 at 6:57

2 Answers 2

3
\$\begingroup\$

SignInAsync is an async method, and you most likely want to wait for it to complete before returning the SignInStatus. In order to await it, we must declare the method with the async keyword. This also means we can simplify the return statements:

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

        await base.SignInAsync(user, isPersistent, shouldLockout);
        return SignInStatus.Success;
    }

    return SignInStatus.Failure;
}
\$\endgroup\$
2
  • \$\begingroup\$ you are right about async. but is the implementation okay? i mean i used signinasync method inside passwordsigninasync and also called membershipprovider inside passwordsigninasync. Is this the correct way to go? \$\endgroup\$
    – th1rdey3
    May 10, 2015 at 13:53
  • \$\begingroup\$ @th1rdey3 sorry, I don't have experience with ASP.NET Identity so can't answer those questions. I hope someone else can help you out there. \$\endgroup\$
    – mjolka
    May 10, 2015 at 14:05
2
\$\begingroup\$

Try using ContinueWith.

I cannot test the Membership Provider part at this time, but the ContinueWith I use in a similar fashion in this exact same method. In your situation PasswordSignInAsync will fail and will give control to ContinueWith and there you can ignore the passed in signInStatus and put your own custom code. Your situation is different in that you don't need to run the base.PasswordSignInAsync(). If so, maybe it is useful to others needing it like I did. In the ContinueWith block I had to put some custom code to run things against our own security framework.

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

                    base.SignInAsync(user, isPersistent, shouldLockout);
                    return SignInStatus.Success;
                }
            }

            return signInStatus.Result;
        });
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.