ASP.NET Core 双因素验证2FA 实战经验分享

640?

必读

本文源码核心逻辑使用AspNetCore.Totp,为什么不使用AspNetCore.Totp而是使用源码封装后面将会说明。

为了防止不提供原网址的转载,特在这里加上原文链接:

双因素认证

双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统。双因素认证是一种采用时间同步技术的系统,采用了基于时间、事件和密钥三变量而产生的一次性密码来代替传统的静态密码。每个动态密码卡都有一个唯一的密钥,该密钥同时存放在服务器端,每次认证时动态密码卡与服务器分别根据同样的密钥,同样的随机参数(时间、事件)和同样的算法计算了认证的动态密码,从而确保密码的一致性,从而实现了用户的认证。就像我们去银行办卡送的口令牌.640?wx_fmt=jpeg

一. 前言

最近公司内部SSO登录一直在找一种安全的方式,目前已实现方案:账号密码登录以及手机验证码登录,通过Apollo切换不同的登录方式,想起18年看到AspNetCore.Totp并也编写了DemodotNetCore-2FA登录,将之前写的再完善并且在此记录和分析,希望对大家有些帮助。

二. AspNetCore.Totp

说明一下为什么要用AspNetCore.Totp修改并且重新打包Brook.TotpAspNetCore.Totp在生成二维码链接时会访问404(google.com)网站,国内基本无法使用,这很不清真,还有就是注入需要注入接口和实现类,使用起来很繁琐,所以才萌生了让使用起来更方便,并且不依赖Google生成二维码的想法

1.生成二维码

accountIdentity = accountIdentity.Replace(" ", "");var encodedSecretKey = Base32.Encode(accountSecretKey);var provisionUrl = UrlEncoder.Encode(string.Format("otpauth://totp/{0}?secret={1}&issuer={2}", accountIdentity, encodedSecretKey, UrlEncoder.Encode(issuer)));var protocol = useHttps ? "https" : "http";var url = $"{protocol}://chart.googleapis.com/chart?cht=qr&chs={qrCodeWidth}x{qrCodeHeight}&chl={provisionUrl}";var totpSetup = new TotpSetup{QrCodeImage = this.GetQrImage(url),ManualSetupKey = encodedSecretKey};

2.注入方式

  • Startup注入

services.AddSingleton<ITotpSetupGenerator, TotpSetupGenerator>();
services.AddSingleton<ITotpValidator, TotpValidator>();
services.AddSingleton<ITotpGenerator, TotpGenerator>();
  • Controller注入

 private readonly ITotpGenerator _totpGenerator;private readonly ITotpSetupGenerator _totpSetupGenerator;private readonly ITotpValidator _totpValidator;public ValuesController(ITotpSetupGenerator totpSetupGenerator){_totpSetupGenerator = totpSetupGenerator;_totpGenerator = new TotpGenerator();_totpValidator = new TotpValidator(_totpGenerator);}

三. Brook.Totp

1.二维码使用QRCoder来生成,不依赖外部网络

        /// <summary>/// 生成二维码/// </summary>/// <param name="provisionUrl"></param>/// <param name="pixelsPerModule"></param>/// <returns></returns>private string GetQrBase64Imageg(string provisionUrl,int pixelsPerModule){QRCodeGenerator qrGenerator = new QRCodeGenerator();QRCodeData qrCodeData = qrGenerator.CreateQrCode(provisionUrl, QRCodeGenerator.ECCLevel.Q);Base64QRCode qrCode = new Base64QRCode(qrCodeData);string qrCodeImageAsBase64 = qrCode.GetGraphic(2);return  $"data:image/png;base64,{qrCodeImageAsBase64}";}

2.注入方式

  • Startup注入

services.AddBrookTotp();
  • Controller注入

private readonly ITotp _totp;
public AccountController(ITotp totp)
{_totp = totp;
}

四.双因素APP

推荐使用Microsoft Authenticator支持IOS、安卓可自动备份

五. 完整流程效果图

使用Microsoft Authenticator640?wx_fmt=jpeg

  1. 正常登录640?wx_fmt=jpeg

  2. 登录成功后绑定,使用Microsoft Authenticator扫描二维码,然后输入显示的6位数字验证码640?wx_fmt=jpeg

  3. 绑定后再次登录640?wx_fmt=jpeg

六.如何使用

所有源代码请参照我的GitHub https://github.com/yuefengkai/Brook.Totp

  1. EF Core In Memory Database所有的数据只存在内存中

  2. Cache in-memory

  3. dotNET Core Authentication

下方只展示部分代码

1.新建netCoreMVC项目添加Nuget包Brook.Totp

640?wx_fmt=jpeg

2.注入方式

  • Startup注入

services.AddMemoryCache();
services.AddSingleton<ICacheManage, CacheManage>();
services.AddBrookTotp();
services.AddDbContext<BrookTotpDBContext>(options => options.UseInMemoryDatabase(databaseName: "BrookTotpDB"));
  • Controller使用

private readonly ITotp _totp;
public AccountController(ITotp totp)
{_totp = totp;
}
//获取二维码
[Authorize]
public IActionResult GetQr()
{var totpSetup = _totp.GenerateUrl("dotNETBuild", CurremtUser.Email, CurremtUser.SecretKeyFor2FA);return Json(new { qrCodeContennt = totpSetup.QrCodeImageContent });
}
//验证双因素校验码
[Authorize]
[HttpPost]
public async Task<IActionResult> Valid(int code)
{var valid = _totp.Validate(CurremtUser.SecretKeyFor2FA, code, 30);if (!valid){return Json(new { result = 0, msg = "2FA校验失败" });}//校验成功后 如果是第一次绑定校验 需将用户的accountSecretKey 存入数据库CurremtUser.IsOpen2FA = true;await _userService.UpdateAsync(CurremtUser);_cacheManage.Remove(string.Format(CacheKeys.GetUserForEmail, CurremtUser.Email));var claims = new List<Claim>{new Claim("user", CurremtUser.Email),new Claim("role", "Member")};await HttpContext.SignInAsync(new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "role")));return Json(new { result = 1, msg = "2FA校验成功", url = "/Home/Index" });
}

七.写在最后

以上所有源代码已开源在 https://github.com/yuefengkai/Brook.Totp

作者:Brook

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结合“性能监视器” 排查、处理性能瓶颈导致应用吞吐率等指标上不去的问题...

双11备战前夕,总绕不过性能压测环节,TPS 一直上不去 / 不达标,除了代码上的问题外,服务器环境、配置、网络、磁盘、CPU 亦是导致性能瓶颈的重要一环,本文旨在分享最近项目性能压测过程中的排查经验,文中的表…

秒半价,限四天!Vostro极致轻薄全能本,助你全能全开!

在信息化时代,电脑就是你工作和创业的“合伙人”!每天比别人多处理几件任务、每天比别人快20分钟,每天比别人少重启和崩溃几次,日积月累获益多到算不过来!小编四处打探,有三款王者电脑重磅优惠,…

【活动】侬好上海,Microsoft Reactor来啦

在美国纽约、旧金山和雷德蒙德,在英国伦敦,在澳大利亚悉尼,在以色列特拉维夫,分别都有这样一处专为开发者打造的宝地,在这些地方:❖ 经常举办各种免费的技术讲座,与大家分享最新技术和产品❖ 频…

A. [2021.1.29多校省选模拟11]最大公约数(杜教筛/数论)

A. [2021.1.29多校省选模拟11]最大公约数 这是一个杜教筛的经典题目,最后我们只需要筛一下1∗xμ(x)1*x\mu(x)1∗xμ(x)这个函数的前缀和即可,然后看到有111这个函数,我们下意识应该想到的就是μ\muμ,然后又有xμ(x)x\mu(x)xμ(x…

.NET Core 小程序开发零基础系列(2)——小程序服务通知(模板消息)

基于上一篇文件“.NET Core 小程序开发零基础系列(1)——开发者启用并校验牵手成功”的反映,个人觉得效果很不错,大家对公众号开发还是有很大需求的,同时也收到了很多同学的问题,后面我也会通过实战性文章慢…

[PowerShell]人人都值得学一点PowerShell实现自动化(2)有哪些可用的场景及方式?

部分读者反应太多知识要学了,学完一轮又一轮,笔者也不想单单为了制造学习而学习,所有Excel催化剂所发布的内容,都是笔者所亲自使用到的,当然很多领域也没有深挖到很底的程度。PowerShell使用场景虽然说PowerShell也是在…

[2021.1.13多校省选模拟2]T1(动态规划/轮廓线dp)

[2021.1.13多校省选模拟2]T1 一个经典的轮廓线dp,可以发现一定可以找到一条轮廓将这个图形分开,然后使得左半部分由左边处理,右半部分由右边处理,然后我们只需要处理这个折线即可,具体实现需要处理前缀和的前缀最大值&…

[PowerShell]人人都值得学一点PowerShell实现自动化(1)在VisualStudio上使用PowerShell...

最近学PowerShell的知识比较多,也开始有一点点可以分享的知识给大家输出,学一门语言,理当首先找准一个好用的IDE来帮助我们提高学习效率,本文给大家介绍如何在宇宙第一的IDE-Visual Studio上写PowerShell脚本。关于PowerShell的基…

[2021.1.17多校省选模拟4]T1(莫比乌斯反演/组合数学/枚举倍数)

[2021.1.17多校省选模拟4]T1 一般人都会想着去枚举直线的斜率,但是枚举斜率之后就会产生多条直线,并且这些直线的长度不一,难以快速求解,所以我们考虑换一种方法枚举。 枚举最远点对的横纵坐标之差,这样很容易计算这…

程序员35岁不转型就退休,是真的吗?

周六下午,DevOps群里,有人贴出来这么一张图:据说,这张图来自于谷歌,Google程序员之间存在这一条鄙视链,站在顶端的是C工程师,其次是Java工程师,再次是Python工程师,接下来…

.net测试篇之Moq框架简单使用

Moq简介Moq是.net平台下的一个非常流行的模拟库,只要有一个接口它就可以动态生成一个对象,底层使用的是Castle的动态代理功能.它的流行赖于依赖注入模式的兴起,现在越来越多的分层架构使用依赖注入的方式来解耦层与层之间的关系.最为常见的是数据层和业务逻辑层之间的依赖注入,…

A. 树与路径(树论/多项式/分治FFT)

A. 树与路径 首先考虑一个dp的方法,对于这种链划分的题目,有一个很重要的思想就是按照每个点的角度考虑,实际上链划分就是匹配问题,每个点只能出一条边和入一条边,所以我们拆点之后就是匹配,这也是网络流最…

.NET Core on K8S学习实践系列文章索引(持续更新)

近期在学习Kubernetes,基于之前做笔记的习惯,已经写了一部分文章,因此给自己立一个2019年的flag:完成这个《.NET Core on K8S学习实践》系列文章!这个系列会持续更新,先发个草稿列表,后续更新&a…

TomatoLog-1.1.0实现ILoggerFactory

TomatoLogTomatoLog 是一个基于 .NETCore 平台的产品。The TomatoLog 是一个中间件,包含客户端、服务端,非常容易使用和部署。客户端实现了ILoggerFactory,使用服务注入成功后即可使用,对业务入侵非常小,也支持通过客户…

Docker(二)-在Docker中部署Nginx实现负载均衡(视频)

一、前言在前面的文章中我们已经介绍了如何在Centos7系统中安装Docker以及利用Docker进行Asp.Net Core应用的部署。在本文中,我们将继续介绍利用Docker部署Nginx服务实现负载均衡,我们通过视频方式向大家进行演示。注:查看公众号历史文章&…

P4389 付公主的背包(生成函数/多项式)

P4389 付公主的背包 https://www.luogu.com.cn/problem/solution/P4389 经典生成函数问题 求解无限背包问题,我们可以将每个物品看作一个多项式,那么最后的结果就是这些多项式的卷积的系数,然后我们实际上就可以考虑分治NTT了,但…

Docker系列之镜像瘦身(五)

本节我们来讲讲在我们在构建镜像过程中不出问题,同时使得最后所构建的镜像文件大小尽可能最小。缓存(cache)Docker的优势之一在于提供了缓存,加速镜像迭代构建,我们知道构建镜像使用docker build命令,也就是说通过docker build的缓…

一张图了解.Net Core和.NetFx和.Net Standard和Xamarin关系

一张图了解.Net Core和.Net Framework和.Net Standard和Xamarin关系总结.NET Standard是一项API规范,每一个特定的版本,都定义了必须实现的基类库。.NET Core是一个托管框架,针对构建控制台、云、ASP.NET Core和UWP应用程序进行了优化。每一种…

Java修炼之路——基础篇——String

String 1:字符串的不可变性 什么是不可变对象?不可变对象是指创建后无法变更的对象 String为什么是不可变的?String类为final,并且内部字符数组也为final。所以String对象是不可变对象。 String类为什么要设计为不可变&#xff1…

VS, VS Code, VS Online, VS xxx, 你都分清了吗?

首先说说部分童鞋容易混淆的 Visual Studio 和 Visual Studio Code 吧。其实,它们俩的关系,就相当于 Java 和 JavaScript,没啥关系。再说说 Visual Studio Online。这就复杂了。历史上,出现过两个 Visual Studio Online&#xff0…