新用户首次登录时强制进行 2 因素身份验证 .NET Core

Posted

技术标签:

【中文标题】新用户首次登录时强制进行 2 因素身份验证 .NET Core【英文标题】:Force 2 Factor Authentication for new users when they login for the first time .NET Core 【发布时间】:2022-01-01 06:19:20 【问题描述】:

当用户第一次登录 .net core 时,我正在尝试配置 2FA。所以我添加了一个 if 条件来检查 2FA 是否未启用然后重定向到创建 MFA,但是,这里的一个主要缺陷是用户可以更改浏览器上的 URL 链接以跳过 2FA 创建,我该如何避免这种情况?以下是我的帐户控制器代码:

登录控制器方法

[HttpGet]
        [AllowAnonymous]
        public IActionResult Login(string? returnurl = null)
        
            ViewData["ReturnUrl"] = returnurl;
            return View();
        

        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> Login(LoginViewModel model, string? returnurl = null)
        
            ViewData["ReturnUrl"] = returnurl;
            returnurl ??= Url.Content("~/");
            if (ModelState.IsValid)
            
                var user = await _userManager.FindByNameAsync(model.UserName);
                var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, lockoutOnFailure: true);
                if (result.Succeeded)
                
                    if (user.TwoFactorEnabled==false)
                    
                        return RedirectToAction(nameof(EnableAuthenticator), new  returnurl, model.RememberMe );
                    
                    return LocalRedirect(returnurl);
                

                if (result.RequiresTwoFactor)
                
                    return RedirectToAction(nameof(VerifyAuthenticatorCode), new  returnurl, model.RememberMe );
                
                if (result.IsLockedOut)
                
                    return View("Lockout");
                
                else
                
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return View(model);
                
            
            return View(model);
        

启用 2FA 控制器方法

    [HttpGet]
    public async Task<IActionResult> EnableAuthenticator()
    
        string AuthenticatorUriFormat = "MY-OTP-SECRET-HERE";

        var user = await _userManager.GetUserAsync(User);
        await _userManager.ResetAuthenticatorKeyAsync(user);
        var token = await _userManager.GetAuthenticatorKeyAsync(user);
        string AuthenticatorUri = string.Format(AuthenticatorUriFormat, _urlEncoder.Encode("My-App-Name-Here"),
            _urlEncoder.Encode(user.Email), token);
        var model = new MFAViewModel()  Token = token, QRCodeUrl = AuthenticatorUri ;
        return View(model);
    

    [HttpPost]
    public async Task<IActionResult> EnableAuthenticator(MFAViewModel model)
    
        if (ModelState.IsValid)
        
            var user = await _userManager.GetUserAsync(User);
            var succeeded = await _userManager.VerifyTwoFactorTokenAsync(user, _userManager.Options.Tokens.AuthenticatorTokenProvider, model.Code);
            if (succeeded)
            
                await _userManager.SetTwoFactorEnabledAsync(user, true);
            
            else
            
                ModelState.AddModelError("Verify", "Your two factor auth code could not be validated.");
                return View(model);
            

        
        return RedirectToAction(nameof(AuthenticatorConfirmation));
    

【问题讨论】:

“用户可以更改浏览器上的 URL 链接以跳过 2FA 创建”是什么意思?从你的代码看来,用户登录成功后,它会检查用户的 TwoFactorEnabled 属性来验证用户是否需要进行 2 Factor Authentication,如何通过更改 URL Link 来控制它? 吕志您好,感谢您的回复,我的要求是执行2FA。所有用户必须在首次登录时注册 2FA。所以根据上面发布的逻辑,一旦用户登录,如果 2FA 被禁用,它就会重定向到 Enable2FA Action 方法。但是,如果我在浏览器上手动更改 URL,它允许我跳过创建 2FA,并访问仪表板。看来我必须使用上述逻辑在每个控制器上检查这一点,我正在为应用程序寻找集中式解决方案。 可以考虑配置应用程序使用Claims-based authorization,用户2FA登录成功后,可以将2FA登录结果添加到一个Claim Store并添加到登录用户。之后,在您的应用程序中,创建一个需要声明的策略,并在每个控制器上添加 Authorize 属性。 此外,您还可以在 2FA 之后添加用户的声明,然后创建自定义中间件/授权属性来验证每个请求并检查当前用户是否包含声明。您可以参考以下链接:Custom Authorization attributes和How To Override Attribute Class To Do Custom Authorization In .NET Core。 亲爱的Zhiv,非常感谢您的解决方案!是的,我会这样做。我将为 2FA 创建一个声明,然后分配属性。 【参考方案1】:

正如我的评论中提到的,您可以考虑配置应用程序使用Claims-based authorization,在用户使用 2FA 成功登录后,您可以添加一个声明存储 2FA 登录结果并将其添加到登录用户。之后,在您的应用程序中,创建一个需要声明的策略,并在每个控制器上添加 Authorize 属性。

此外,您还可以在 2FA 之后添加用户的声明,然后创建自定义中间件/授权属性来验证每个请求并检查当前用户是否包含声明。可以参考以下链接:Custom Authorization attributes和How To Override Attribute Class To Do Custom Authorization In .NET Core。

【讨论】:

以上是关于新用户首次登录时强制进行 2 因素身份验证 .NET Core的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core 中首次登录时强制重定向到另一个页面

AWS Amplify/Cognito - 一种仅在用户首次登录时设置 TOTP MFA 的方法

keycloak-connect nodejs / meteor - 仅在首次登录时拒绝访问且仅在 prod

Facebook iOS SDK - 第二次登录时多余的“确定”点击?

首次登录时创建教程

使用 LDAP 身份验证处理用户关系 [关闭]