网站首页 网站源码
using System.Text;
using Dpz.Core.Auth.Models;
using Dpz.Core.Authenticator;
using Dpz.Core.Service.RepositoryService;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Dpz.Core.Auth.Controllers;
public class TwoFactorController(
ILogger<HomeController> logger,
IUserTwoFactorService userTwoFactorService
) : Controller
{
/// <summary>
/// 绑定双因素验证
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize]
[Route("two-factor.html")]
public async Task<IActionResult> BindTwoFactor(string returnUrl = "/")
{
var account = User.NameIdentifier;
if (User.Identity?.IsAuthenticated != true || string.IsNullOrWhiteSpace(account))
{
return Challenge(authenticationSchemes: ConstValues.DefaultScheme);
}
var (key, isBind) = await userTwoFactorService.GetKeyAsync(account);
if (isBind)
{
return Redirect(returnUrl);
}
if (!isBind && string.IsNullOrWhiteSpace(key))
{
logger.LogWarning("获取用户密钥失败,账号:{Account}", account);
return Redirect(returnUrl);
}
var twoFactorAuthenticator = new TwoFactorAuthenticator();
var setupInfo = twoFactorAuthenticator.GenerateSetupCode(
issuer: "叫我阿胖",
accountTitleNoSpaces: account,
accountSecretKey: key,
secretIsBase32: false
);
TempData["FromUrl"] = returnUrl;
return View(setupInfo);
}
[HttpGet]
[Authorize]
[Route("unbind-two-factor.html")]
public async Task<IActionResult> UnBindTwoFactor()
{
var account = User.NameIdentifier;
var (_, isBind) = await userTwoFactorService.GetKeyAsync(account);
if (!isBind)
{
TempData["Msg"] = "您未绑定双因素验证";
}
return View();
}
[ValidateAntiForgeryToken]
[Authorize]
[HttpPost]
[Route("handel-bind-two-factor")]
public async Task<IActionResult> HandleBindTwoFactor(string pinCode, string returnUrl = "/")
{
var account = User.NameIdentifier;
if (User.Identity?.IsAuthenticated != true || string.IsNullOrWhiteSpace(account))
{
return Challenge(authenticationSchemes: ConstValues.DefaultScheme);
}
var (key, isBind) = await userTwoFactorService.GetKeyAsync(account);
if (isBind)
{
return Redirect(returnUrl);
}
if (!isBind && string.IsNullOrWhiteSpace(key))
{
logger.LogWarning("获取用户密钥失败,账号:{Account}", account);
return Redirect(returnUrl);
}
var twoFactorAuthenticator = new TwoFactorAuthenticator();
var keyBuffer = Encoding.UTF8.GetBytes(key);
var keyBase32 = Base32Encoding.ToString(keyBuffer);
var twoFactorResult = twoFactorAuthenticator.ValidateTwoFactorPIN(keyBase32, pinCode, true);
if (!twoFactorResult)
{
TempData["Msg"] = "PIN码验证失败";
return RedirectToAction("BindTwoFactor", new { fromUrl = returnUrl });
}
await userTwoFactorService.BindAsync(account);
return Redirect(returnUrl);
}
[HttpPost]
[Authorize]
[Route("unbind-two-factor")]
public async Task<IActionResult> HandleUnbindTwoFactor(
[FromQuery] string returnUrl,
string pinCode
)
{
var account = User.NameIdentifier;
if (User.Identity?.IsAuthenticated != true || string.IsNullOrWhiteSpace(account))
{
return Challenge(authenticationSchemes: ConstValues.DefaultScheme);
}
var (key, isBind) = await userTwoFactorService.GetKeyAsync(account);
if (!isBind)
{
TempData["Msg"] = "您未绑定双因素验证";
return RedirectToAction("BindTwoFactor", new { returnUrl });
}
var twoFactorAuthenticator = new TwoFactorAuthenticator();
var keyBuffer = Encoding.UTF8.GetBytes(key);
var keyBase32 = Base32Encoding.ToString(keyBuffer);
var twoFactorResult = twoFactorAuthenticator.ValidateTwoFactorPIN(keyBase32, pinCode, true);
if (!twoFactorResult)
{
TempData["Msg"] = "PIN码验证失败";
return RedirectToAction("UnBindTwoFactor", new { returnUrl });
}
await userTwoFactorService.UnbindAsync(account);
return Redirect(returnUrl);
}
}
上述代码是一个 ASP.NET Core 控制器,名为 TwoFactorController,用于处理用户的双因素身份验证(2FA)相关操作。以下是代码的主要功能和结构的详细解释:
Dpz.Core.Auth.Controllers,表明这是一个与身份验证相关的控制器。ILogger<HomeController> 和 IUserTwoFactorService,用于记录日志和处理用户的双因素验证逻辑。控制器提供了以下几个主要功能:
BindTwoFactor/two-factor.htmlUnBindTwoFactor/unbind-two-factor.htmlHandleBindTwoFactor/handel-bind-two-factorHandleUnbindTwoFactor/unbind-two-factor这个控制器实现了双因素身份验证的绑定和解绑功能,确保用户在进行敏感操作时能够通过额外的身份验证步骤来提高安全性。通过使用 ASP.NET Core 的身份验证和授权机制,确保只有经过身份验证的用户才能访问这些功能。
