asp.net-core - 如何在 .Net Core Identity 中实现 2FA?

标签 asp.net-core authentication asp.net-core-identity

问题:如何强制现有用户在 .Net Core 3.1 Identity 中设置 2FA?

我已经在这里看到了一些答案,但我对它们有如下问题:

  1. 如果用户尚未设置 2FA 页面,则将其重定向至登录时设置。问题是用户可以简单地跳转到不同的 url 来避免这种情况,因此实际上并没有强制执行。

  2. 执行一些过滤器,检查用户是否启用了 2FA,如果没有,则将其重定向到 MFA 设置页面。我遇到的问题是,在每次导航时,服务器都必须访问数据库来检查用户是否启用了此字段,从而对每个请求造成显着的性能影响。我知道一次数据库访问可能听起来不多,但我曾经使用过这样的应用程序,这是常态,其他事情也使用这种方法,导致一堆预操作数据库查询。除非绝对必要,否则我想避免这种行为。

我当前的想法是登录时:

  1. 检查用户凭据但不登录

    userManager.CheckPasswordAsync(....)

  2. 如果凭据通过,请检查用户是否启用了 2FA。如果是,则继续执行登录流程,如果不是:

  3. 生成用户 token :

    userManager.GenerateUserTokenAsync(.......)

并将其与用户名一起存储在服务器端缓存中。然后将 key 传递给缓存项目,并重定向到 2FA 设置页面,该页面不会设置 [authorize] 属性,允许未登录的用户访问它。

  • 在 2FA 设置页面上执行任何操作之前,请使用提供的 key 检索缓存的项目并验证 token 和用户名:

    userManager.VerifyUserTokenAsync(......)

  • 如果未通过,则返回 Unauthorized,否则继续并从通过缓存键传递的 URL 中提供的 UserName 获取当前用户。还要转储缓存的项目和 key ,以便 URL 被狡猾的浏览器扩展抢夺时无法再次使用。

  • 继续将新的缓存 key 传递给每个 2FA 页面的新用户 token 和用户名,以在用户导航时对用户进行身份验证。

  • 这是用户 token 的适当使用吗?这种方法足够安全吗?我担心用户未登录会带来安全问题,但我认为为了避免前面提到的在每个请求检查 2FA 时都访问数据库的问题,有必要这样做,因为尝试导航离开的方法将只需重定向到登录即可。

    最佳答案

    我通过 Filter Method 实现了这个

    我有一个 BasePageModel,我的所有页面都继承它

    public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {
        if (!User.Identity.IsAuthenticated)
        {
            await next.Invoke();
    
            return;
        }
    
        var user = await UserManager.GetUserAsync(User);
    
        var allowedPages = new List<string>
        {
            "Areas_Identity_Pages_Account_ConfirmEmail",
            "Areas_Identity_Pages_Account_ConfirmEmailChange",
            "Areas_Identity_Pages_Account_Logout",
            "Areas_Identity_Pages_Account_Manage_EnableAuthenticator",
            "Areas_Identity_Pages_Account_ResetPassword",
            "Pages_AllowedPageX",
            "Pages_AllowedPageY",
            "Pages_Privacy"
        };
    
        var page = context.ActionDescriptor.PageTypeInfo.Name;
    
        if (!user.TwoFactorEnabled && allowedPages.All(p => p != page))
        {
            context.Result = RedirectToPage("/Account/Manage/EnableAuthenticator", new { area = "Identity" });
        }
        else
        {
            await next.Invoke();
        }
    }
    

    然后,我更改了 Disable2faResetAuthenticator 页面以重定向到主 2fa 页面

    public IActionResult OnGet() => RedirectToPage("./TwoFactorAuthentication");
    

    并从该页面删除了重置/禁用链接

    关于asp.net-core - 如何在 .Net Core Identity 中实现 2FA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66486574/

    相关文章:

    asp.net-core-2.0 - IdentityServer4 签名 key 、验证 key 和 .Net Core 数据保护

    azure-active-directory - Asp.net Core 2.1-* 中用于 Multi-Tenancy 的动态 OpenIdConnectOptions

    c# - Entity Framework 核心 : Get changes occured in entity and related data

    c# - 无法解析 JSON 文件,Progam.cs asp.net core 中出错

    asp.net-core - 为什么没有应用api版本?

    asp.net-core - 如何使用 Miniprofiler 存储来支持多个 Web 实例?

    api - 如何从服务器和客户端角度使用3Scale的 `authrep`函数?

    sql-server - 从域管理员保护 SQL Server 数据库

    android - 如何在 Android 应用程序中保持与 facebook 的连接

    asp.net-core - .NET Core 2.1 MVC Identity Authorization - 不同部分的不同用户角色