验证 ASP.NET Identity 中的自定义登录规则,但浏览器仍重定向到主页

Posted

技术标签:

【中文标题】验证 ASP.NET Identity 中的自定义登录规则,但浏览器仍重定向到主页【英文标题】:Custom login rules in ASP.NET Identity are validated, but browser still redirects to Home 【发布时间】:2018-05-30 01:07:51 【问题描述】:

在 ASP.NET MVC5 中,我使用的是 ASP.NET Identity,除了 PasswordSignInAsync 之外,我还必须通过向 PasswordSignInAsync 添加一个 PasswordSignInAsync 重载和一个附加属性来存储状态来实现一些自定义登录规则:

public class ApplicationSignInManager : SignInManager<ApplicationUser, string>

    public EnumCompanyStatus CompanyStatus  get; private set; 

    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager)
    
        CompanyStatus = EnumCompanyStatus.Active;
    

    // Standard scaffolding omitted

    public async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout, Func<string, EnumCompanyStatus> getCompanyStatus)
    
        SignInStatus signInStatus = await base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout);

        if (signInStatus == SignInStatus.Success)
        
            CompanyStatus = getCompanyStatus(userName);

            if (CompanyStatus != EnumCompanyStatus.Active)
                signInStatus = SignInStatus.Failure;
        

        return signInStatus;
    

这是我在AccountController 中的登录方法:

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

        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false, GetCompanyStatus);

        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:
                if (SignInManager.CompanyStatus == EnumCompanyStatus.Disabled)
                    ModelState.AddModelError("", "User disabled.");
                else if (SignInManager.CompanyStatus == EnumCompanyStatus.Frozen)
                    ModelState.AddModelError("", "Please contact our support.");
                else
                    ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        
    

我的问题在于switch/case 语句中的default 情况。每当SignInManager.CompanyStatusDisabledFrozen 时,都会正确访问此相应代码,但是,大多数时候用户仍将被重定向到主页,而不是仅仅获得应用程序打印我的错误信息。它已经工作了几次,但我的断点妨碍了我。如果执行达到最后一个条件,即传统的登录失败尝试,它可以完美运行(错误消息显示在登录页面中并且没有发生重定向),但 .NET 似乎对我对signInStatus 的搞砸不太满意.我在这里想念什么?我只能想象有另一个属性阻碍了我,但我多年来一直在处理 Web 开发,我现在真的可以使用一些帮助。

【问题讨论】:

【参考方案1】:

在摸索了一会儿之后,我认为是的,PasswordSignInAsync 确实在改变一个内部状态,无论我后来做了什么,它都验证了我的请求。所以我只是交换了自定义验证和基本方法调用的顺序:

    public async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout, Func<string, EnumCompanyStatus> getCompanyStatus)
    
        CompanyStatus = getCompanyStatus(userName);

        if (CompanyStatus != EnumCompanyStatus.Active)
            return SignInStatus.Failure;

        return await base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout);
    

【讨论】:

以上是关于验证 ASP.NET Identity 中的自定义登录规则,但浏览器仍重定向到主页的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Identity - 扩展密码哈希

如何从 ASP.NET Core 2.0 中的自定义中间件请求身份验证

asp.net core系列 48 Identity 身份模型自定义

如何使用 ASP.NET Core Identity 将登录/注册系统添加到现有数据库?

ASP.NET MVC 5 中的简单角色管理器和授权,无需使用 Identity(CustomRoleProvider)

asp.net core 2.0 授权在身份验证(JWT)之前触发