在 ASP.NET Core Identity(独立)中,您如何执行 2FA?
In ASP.NET Core Identity (standalone), how do you enforce 2FA?
我在 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();
}
我确实找到了这个 但它似乎需要 OpenIdConnect。我正在使用独立身份。
我从 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;
}
}
}
此外,在启动的 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"));
});
然后我没有向每个 OnGet
方法添加 if
逻辑,而是添加
[Authorize(Policy = "TwoFactorEnabled")]
在代码隐藏文件的顶部,例如:
[Authorize(Policy = "TwoFactorEnabled")]
public class DetailModel : PageModel
{
我在 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/ 开始 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;
}
}
}
此外,在启动的 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"));
});
然后我没有向每个 OnGet
方法添加 if
逻辑,而是添加
[Authorize(Policy = "TwoFactorEnabled")]
在代码隐藏文件的顶部,例如:
[Authorize(Policy = "TwoFactorEnabled")]
public class DetailModel : PageModel
{