【问题标题】:In ASP.NET Core Identity (standalone), how do you enforce 2FA?在 ASP.NET Core Identity(独立)中,如何强制执行 2FA?
【发布时间】:2021-08-31 07:49:55
【问题描述】:

我在 Razor Pages 项目中使用 ASP.NET Core Identity。 如果经过身份验证的用户不符合特定策略(例如未启用 2FA),您如何重定向到特定页面(例如启用 2FA 页面)?

我希望避免在每个 OnGet 中检查声明,例如:

    public IActionResult OnGet()
    {
        var claimTwoFactorEnabled = User.Claims.FirstOrDefault(t => t.Type == "TwoFactorEnabled");

        if (claimTwoFactorEnabled != null && "true".Equals(claimTwoFactorEnabled.Value))
        {
            // You logged in with MFA, do the admin stuff
        }
        else
        {
            return Redirect("/Identity/Account/Manage/TwoFactorAuthentication");
        }

        return Page();
    }

(如https://damienbod.com/2020/01/03/requiring-mfa-for-admin-pages-in-an-asp-net-core-identity-application/中所述)

我确实找到了这个answer,但它似乎需要 OpenIdConnect。我正在使用独立的身份。

【问题讨论】:

  • 你读过the docs吗?通常最好的地方也是先看。
  • 那里有一个独立的身份示例,需要上面的代码块;我想看看是否有另一种解决方案不涉及检查每个 OnGet 中的声明。

标签: asp.net .net-core identity


【解决方案1】:

我从https://damienbod.com/2020/01/03/requiring-mfa-for-admin-pages-in-an-asp-net-core-identity-application/开始使用AdditionalUserClaimsPrincipalFactory

using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
 
namespace IdentityStandaloneMfa
{
    public class AdditionalUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser, IdentityRole>
    {
        public AdditionalUserClaimsPrincipalFactory( 
            UserManager<IdentityUser> userManager,
            RoleManager<IdentityRole> roleManager, 
            IOptions<IdentityOptions> optionsAccessor) 
            : base(userManager, roleManager, optionsAccessor)
        {
        }
 
        public async override Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
        {
            var principal = await base.CreateAsync(user);
            var identity = (ClaimsIdentity)principal.Identity;
 
            var claims = new List<Claim>();
 
            if (user.TwoFactorEnabled)
            {
                claims.Add(new Claim("TwoFactorEnabled", "true"));
            }
            else
            {
                claims.Add(new Claim("TwoFactorEnabled", "false")); ;
            }
 
            identity.AddClaims(claims);
            return principal;
        }
    }
}

另外,在 Startup 的 ConfigureServices 中,添加了:

   services.AddAuthorization(options =>
            {
                options.AddPolicy("TwoFactorEnabled",
                    x => x.RequireClaim("TwoFactorEnabled", "true")
                );
                // you can also combine with a role based policy
                options.AddPolicy("RequireAdminRole",
                    policy => policy.RequireRole("Admin", "SuperAdmin").RequireClaim("TwoFactorEnabled", "true"));

            });

然后,我没有将 if 逻辑添加到每个 OnGet 方法中,而是添加 [Authorize(Policy = "TwoFactorEnabled")] 在代码隐藏文件的顶部,例如:

    [Authorize(Policy = "TwoFactorEnabled")]
    public class DetailModel : PageModel
    {

【讨论】:

  • ConfigureServices 中的代码应查找您添加给用户的声明,以表明他们正在 AdditionalUserClaimsPrincipalFactory 中使用 MFA - 在 AdditionalUserClaimsPrincipalFactory 代码中是声明“TwoFactorEnabled”,值为“true”。因此,您在 ConfigureServices 中添加到 MFA 授权的策略应该是:options.AddPolicy("TwoFactorEnabled", x =&gt; x.RequireClaim("TwoFactorEnabled", "true"));
  • 谢谢@PeterG!接得好。我已经用您的更正更新了答案。 (显然我混淆了两个不同的例子;其中一个对我有用。)
猜你喜欢
  • 1970-01-01
  • 2021-06-03
  • 2020-02-15
  • 2016-07-21
  • 2015-07-30
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多