# .Net 使用多重要素驗證(免費方案) ###### tags: `.net core` `Auth` #### [來源連結](https://blog.darkthread.net/blog/mfa-with-ms-authenticator/) 驗證功能部分需安裝套件Otp.Net,QrCode產生部分參閱[另一篇筆記 ](https://hackmd.io/pfJWhzFiR96PD78eQC-EGA) ### Controller ``` public IActionResult Index(string Result=null) { //string sercret = Uri.EscapeDataString(Base32Encoding.ToString(KeyGeneration.GenerateRandomKey())); string sercret = "7FXZV4THYPNLWPJHYFRNT7D2VWHZXUF7"; //實務上需另外儲存且每個人各不相同 ViewBag.QrCode =_qrcodeHelper.CreateQrCode(_MFAHelper.GenQRCodeUrl(sercret)); ViewBag.Sercret = sercret; ViewBag.Result = Result; return View(); } public IActionResult VaildCode(string Code,string Secret) { var Result = _MFAHelper.ValidateTotp(Code,Secret); if(Result.Item1) //驗證通過 { } return RedirectToAction("Index", new { Result = Result.Item2 }); } ``` ### View ``` @{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <form action="Home/VaildCode"> <div> <p>@ViewBag.Result</p> <label> 請輸入驗證碼 <input name="Code" type="text"> <input hidden="hidden" name="Secret" type="text" value='@ViewBag.Sercret'> </label> <button type="submit">送出</button> </div> </form> <img alt="" src='@ViewBag.QrCode' /> </div> ``` ### Helper ``` public class MFAuthenticationHelper { //需安裝套件Otp.Net public string GenQRCodeUrl(string Secret,string Lable="Dino",string Issuer= "TOTP測試") { return $"otpauth://totp/{Lable}?issuer={Uri.EscapeDataString(Issuer)}&secret={Secret}"; } public (bool,string) ValidateTotp(string totp,string Secret = null, Totp totpInstance = null) { try { if(totp == null || Secret==null && totpInstance == null) return (false, "驗證失敗"); if (totpInstance == null) totpInstance = new Totp(Base32Encoding.ToBytes(Secret)); long timedWindowUsed; if (totpInstance.VerifyTotp(totp, out timedWindowUsed)) return (true,$"驗證通過 - {timedWindowUsed}"); else return (false, "驗證失敗"); } catch (Exception ex) { Console.WriteLine("{0} Top Vaild Faill:{1}",DateTime.Now,ex.ToString()); return (false, "驗證失敗"); } } } ```