自定义ASP.Net Identity登录有效,但IsAuthenticated并不

时间:2015-10-22 18:47:15

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

我正在使用已启用Identity的空/新MVC5 Web项目。我已经定制了IdentityModel.cs来使用我们的表/模式来获取用户登录。

我可以登录并获取SignInStatus.Success,但是当页面加载_LoginPartial.cshtml文件时,它就像Request.IsAuthenticated == false一样。在覆盖时是否有我遗漏的东西?

我的AccountController.cs方法如下所示:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    var result = await CustomSignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return View(model);
    }
}

以下是支持自定义类:

public class CustomSignInManager : SignInManager<CustomUser, string>
{
    public CustomSignInManager(CustomUserManager userManager, IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
    }

    public static CustomSignInManager Create(IdentityFactoryOptions<CustomSignInManager> options, IOwinContext context)
    {
        return new CustomSignInManager(context.GetUserManager<CustomUserManager>(), context.Authentication);
    }

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

        var user = await UserManager.FindByNameAsync(userName).WithCurrentCulture();
        if (user == null)
        {
            return SignInStatus.Failure;
        }

        if (UserManager.SupportsUserPassword
            && await UserManager.CheckPasswordAsync(user, password)
                                .WithCurrentCulture())
        {
            return SignInStatus.Success;
        }
        if (shouldLockout && UserManager.SupportsUserLockout)
        {
            // If lockout is requested, increment access failed count
            // which might lock out the user
            await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture();
            if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
            {
                return SignInStatus.LockedOut;
            }
        }
        return SignInStatus.Failure;
    }
}

我的CustomUserManager:

public class CustomUserManager : UserManager<CustomUser>
{
    public CustomUserManager(IUserStore<CustomUser> store)
        : base(store)
    {
        this.PasswordHasher = new SQLPasswordHasher();
    }

    public static CustomUserManager Create()
    {
        var manager = new CustomUserManager(new CustomUserStore());
        return manager;
    }

    public override bool SupportsUserLockout {
        get { return false; } 
    }

    public override bool SupportsUserPassword
    {
        get { return true; }
    }

    // CheckPasswordAsync
    public override Task<bool> CheckPasswordAsync(CustomUser user, string password)
    {
        return Task.Run(() => MyCheckPasswordAsync( user, password));
    }

    private bool MyCheckPasswordAsync(CustomUser user, string password)
    {
        using (var db = new MkpContext())
        {
            var profile = (
                from pi in db.ProfileIdentifier
                join p in db.Profile on pi.ProfileId equals p.ProfileId
                where
                    pi.ProfileIdentifierTypeId == (int) ProfileIdentifierTypes.email &&
                    pi.ProfileIdentifierValue == user.UserName &&
                    pi.IsActive
                select p).FirstOrDefault(); // Use email to find profileId

            if (profile == null || profile.ProfileId == Guid.Empty) return false;

            // Verify password
            var verPassResults = PasswordHasher.VerifyHashedPassword(profile.Password + "|" + profile.PasswordSalt,
                password);

            // Check if valid password
            if (verPassResults == PasswordVerificationResult.Failed || password == string.Empty) return false;
        }

        return true;
    }
}

1 个答案:

答案 0 :(得分:1)

因为您根本就没有登录用户!您只需检查用户是否可以登录然后返回成功结果而不是实际登录。只需更改您的PasswordSignInAsync()方法,如下所示:

public override async Task<SignInStatus> PasswordSignInAsync(
    string userName,
    string password,
    bool isPersistent,
    bool shouldLockout)
{
    // other parts

    if (UserManager.SupportsUserPassword
        && await UserManager.CheckPasswordAsync(user, password)
                            .WithCurrentCulture())
    {
        // this method actually do the job
        return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
    }

    // rest of code
}