You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2 Identity添加SMS多因素认证方案咨询

我刚好在ASP.NET Core 2.0 Identity里实现过SMS多因素认证,给你梳理一套贴合新版架构的实操步骤,比旧文档的示例更实用:

核心实现步骤

1. 先搭建短信发送服务

首先需要一个能发送短信的服务,你可以对接第三方短信平台(比如Twilio、阿里云短信),先写个接口和实现示例:

// 定义短信发送接口
public interface ISmsSender
{
    Task SendSmsAsync(string phoneNumber, string message);
}

// 模拟实现(生产环境要替换成真实服务商调用)
public class SmsSender : ISmsSender
{
    public async Task SendSmsAsync(string phoneNumber, string message)
    {
        // 这里替换成你用的短信API调用逻辑
        // 比如Twilio的:await _twilioClient.Messages.CreateAsync(...)
        Console.WriteLine($"发送短信到 {phoneNumber}:{message}");
        await Task.CompletedTask;
    }
}

然后在Startup.cs的ConfigureServices里注册这个服务:

services.AddTransient<ISmsSender, SmsSender>();

2. 配置Identity的SMS TokenProvider

在Identity配置里,添加手机号对应的Token生成器,让Identity能生成用于SMS验证的验证码:

services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    // 添加手机号TokenProvider,自定义名称"Phone"后续会用到
    .AddTokenProvider<PhoneNumberTokenProvider<IdentityUser>>("Phone");

3. 完善用户手机号绑定流程

用户必须先绑定手机号才能用SMS MFA,所以要在账户管理页面(比如Manage/Index)添加绑定逻辑:

  • 用户输入手机号后,点击「发送验证码」:
    var user = await _userManager.GetUserAsync(User);
    var verificationCode = await _userManager.GenerateChangePhoneNumberTokenAsync(user, inputPhoneNumber);
    await _smsSender.SendSmsAsync(inputPhoneNumber, $"你的手机号绑定验证码:{verificationCode}");
    
  • 用户输入验证码后,完成绑定:
    var result = await _userManager.ChangePhoneNumberAsync(user, inputPhoneNumber, inputCode);
    if (result.Succeeded)
    {
        await _signInManager.RefreshSignInAsync(user);
        // 绑定成功提示
    }
    

4. 调整登录流程的MFA分支

在登录的Post方法里,验证密码成功后,判断用户是否启用了SMS MFA:

var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
    var user = await _userManager.FindByEmailAsync(Input.Email);
    if (await _userManager.GetTwoFactorEnabledAsync(user))
    {
        // 获取用户可用的MFA方式
        var validProviders = await _userManager.GetValidTwoFactorProvidersAsync(user);
        if (validProviders.Contains("Phone"))
        {
            // 生成SMS验证码并发送
            var smsCode = await _userManager.GenerateTwoFactorTokenAsync(user, "Phone");
            await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), $"你的登录验证码:{smsCode}");
            
            // 跳转到验证码输入页,传递MFA类型为"Phone"
            return RedirectToAction(nameof(VerifyCode), new { provider = "Phone", returnUrl = returnUrl, rememberMe = Input.RememberMe });
        }
        // 如果只有Authenticator,就跳转到对应的验证页
        return RedirectToAction(nameof(VerifyCode), new { provider = "Authenticator", returnUrl = returnUrl, rememberMe = Input.RememberMe });
    }
    // 未启用MFA,直接登录
    return LocalRedirect(returnUrl);
}

5. 验证码验证逻辑

在VerifyCode页面,处理SMS验证码的验证:

var result = await _signInManager.TwoFactorSignInAsync(Input.Provider, Input.Code, Input.RememberMe, rememberClient: Input.RememberMe);
if (result.Succeeded)
{
    return LocalRedirect(returnUrl);
}
else if (result.IsLockedOut)
{
    return RedirectToAction(nameof(Lockout));
}
else
{
    ModelState.AddModelError(string.Empty, "无效的验证码,请重新输入");
    return Page();
}
关键注意事项
  • 生产环境一定要替换SmsSender的模拟实现为正规短信服务商的API调用,避免验证码无法发送
  • 可以在Startup.cs里配置验证码有效期:
    services.Configure<DataProtectionTokenProviderOptions>(options =>
    {
        options.TokenLifespan = TimeSpan.FromMinutes(5); // 验证码5分钟内有效
    });
    
  • 要处理用户未绑定手机号却想启用SMS MFA的情况,引导用户先完成手机号绑定

内容的提问来源于stack exchange,提问作者cgipson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:19:17