Privacy Policy
Core logic source used herein AspNetCore.Totp , why not use AspNetCore.Totp
but the use of the package will be described later source.
To prevent reprint does not provide the original URL, add special text link here:
https://www.cnblogs.com/yuefengkai/p/11408339.html
Two-factor authentication
Two-factor authentication is through you know these two factors plus you can have grouped together to play a role in the authentication system. The use of two-factor authentication is a time synchronization technology system that uses a time-based one-time password, key events and three-variable generated to replace the traditional static passwords. Each dynamic password card has a unique key that is stored on the server at the same time, the dynamic password card every time the server according to the same key, respectively, the same random parameters (time, event), and the same authentication algorithm calculates a dynamic password authentication, ensuring consistency password, enabling user authentication. As we go to the bank to do card to send the password card.
I. Introduction
Recent internal SSO login has been looking for a safe way, the current program has been implemented: the account password and phone verification code by Apollo switch to a different login, remembered 18 years to see AspNetCore.Totp and also prepared a Demo dotNetCore -2FA login, before you write will sound again and this recording and analysis, we want some help.
Two. AspNetCore.Totp
Explain why use AspNetCore.Totp
modified and repackaged Brook.Totp
result AspNetCore.Totp
in the generation of two-dimensional code links to access 404 (google.com) website, the country simply can not use, this is not Muslim , there is a need to inject injecting interface and implementation class, using up very tedious, so make it easier for the initiation of use, and does not rely on Google to generate two-dimensional code
- Generate two-dimensional code
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
};
- Injection method
Startup injection
services.AddSingleton<ITotpSetupGenerator, TotpSetupGenerator>();
services.AddSingleton<ITotpValidator, TotpValidator>();
services.AddSingleton<ITotpGenerator, TotpGenerator>();
Controller injection
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);
}
Three. Brook.Totp
- A two-dimensional code used
QRCoder
to generate the two-dimensional code, does not rely on external network
/// <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}";
}
- Injection method
Startup injection
services.AddBrookTotp();
Controller injection
private readonly ITotp _totp;
public AccountController(ITotp totp)
{
_totp = totp;
}
IV. Two-factor APP
Recommended use Microsoft Authenticator support IOS, Android can automatically backup
before using Google Authenticator phone is broken Gitlab and DropBox can no longer get in (distressed that their three seconds)
V. complete process renderings
Use Microsoft Authenticator
- Normal login
- After a successful login Bind
- Log in again after binding
VI. How to use
All the source code, please refer to my GitHub https://github.com/yuefengkai/Brook.Totp
Demo in use
EF Core In Memory Database
All data exists only in memoryCache in-memory
dotNET Core Authentication
Below only shows part of the code
- New items are added Nuget package netCoreMVC
Brook.Totp
- Startup injection
services.AddMemoryCache();
services.AddSingleton<ICacheManage, CacheManage>();
services.AddBrookTotp();
services.AddDbContext<BrookTotpDBContext>(options => options.UseInMemoryDatabase(databaseName: "BrookTotpDB"));
- Controller uses
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" });
}
VII. Written in the last
All of the above source code has been open sourced https://github.com/yuefengkai/Brook.Totp
If you find it useful, please give me a Start!
Author: Brook (high Zengzhi)