使用 SMS 和電子郵件雙因素驗證的 ASP.NET MVC 5 應用程式

作者: Rick Anderson

本教學課程說明如何使用 Two-Factor 驗證來建置 ASP.NET MVC 5 Web 應用程式。 您應該先完成 建立安全 ASP.NET MVC 5 Web 應用程式,並登入、電子郵件確認和密碼重設 ,再繼續進行。 您可以 在這裡下載已完成的應用程式。 下載包含偵錯協助程式,可讓您測試電子郵件確認和 SMS,而不需設定電子郵件或 SMS 提供者。

本教學課程是由 Rick Anderson ( Twitter 所撰寫: @RickAndMSFT ) 。

建立 ASP.NET MVC 應用程式

從安裝並執行Visual Studio Express 2013 for Web或更高版本開始。

注意

警告:您應該先完成 建立安全 ASP.NET MVC 5 Web 應用程式並登入、電子郵件確認和密碼重設 ,再繼續進行。 您必須安裝Visual Studio 2013 Update 3或更高版本,才能完成本教學課程。

  1. 建立新的 ASP.NET Web 專案,然後選取 MVC 範本。 Web Form也支援 ASP.NET 身分識別,因此您可以遵循 Web 表單應用程式中的類似步驟。
    顯示 [新增 S P 點 NET 專案] 視窗的螢幕擷取畫面。預設驗證 [個別使用者帳戶] 會反白顯示。
  2. 將預設驗證保留為 [個別使用者帳戶]。 如果您想要在 Azure 中裝載應用程式,請保留核取方塊。 稍後在本教學課程中,我們將部署至 Azure。 您可以 免費開啟 Azure 帳戶
  3. 專案設定為使用 SSL

設定雙因素驗證的 SMS

本教學課程提供使用 Twilio 或 ASPSMS 的指示,但您可以使用任何其他 SMS 提供者。

  1. 使用 SMS 提供者建立使用者帳戶

    建立 TwilioASPSMS 帳戶。

  2. 安裝其他套件或新增服務參考

    Twilio:
    在 [套件管理器主控台] 中,輸入下列命令:
    Install-Package Twilio

    ASPSMS:
    必須新增下列服務參考:

    顯示 [新增服務參考] 視窗的螢幕擷取畫面。[位址] 和 [命名空間] 輸入列會反白顯示。

    位址:
    https://webservice.aspsms.com/aspsmsx2.asmx?WSDL

    命名空間:
    ASPSMSX2

  3. 找出 SMS 提供者使用者認證

    Twilio:
    從 Twilio 帳戶的 [ 儀表板 ] 索引標籤中,複製 [帳戶 SID ] 和 [ 驗證] 權杖

    ASPSMS:
    從您的帳戶設定中,流覽至 Userkey ,並將它與您的自我定義 密碼一起複製。

    我們稍後會將這些值儲存在索引鍵 "SMSAccountIdentification""SMSAccountPassword" 內的web.config檔案中。

  4. 指定 SenderID / Originator

    Twilio:
    從 [ 號碼] 索引 標籤中,複製您的 Twilio 電話號碼。

    ASPSMS:
    在 [ 解除鎖定原始程式 ] 功能表中,解除鎖定一或多個 [原始程式],或選擇英數位元來源器 (所有網路) 不支援。

    我們稍後會將此值儲存在索引鍵 "SMSAccountFrom" 內的web.config檔案中。

  5. 將 SMS 提供者認證傳輸至應用程式

    讓應用程式可以使用認證和寄件者電話號碼。 為了保持簡單,我們會將這些值儲存在 web.config 檔案中。 當我們部署至 Azure 時,我們可以將值安全地儲存在網站設定索引標籤上的 [應用程式設定 ] 區段中。

    </connectionStrings>
       <appSettings>
          <add key="webpages:Version" value="3.0.0.0" />
          <!-- Markup removed for clarity. -->
          <!-- SendGrid-->
          <add key="mailAccount" value="account" />
          <add key="mailPassword" value="password" />
          <add key="SMSAccountIdentification" value="My Identification" />
          <add key="SMSAccountPassword" value="My Password" />
          <add key="SMSAccountFrom" value="+12065551234" />
       </appSettings>
      <system.web>
    

    警告

    安全性 - 永不將敏感性資料儲存在您的原始程式碼中。 帳戶和認證會新增至上述程式碼,以便讓範例保持簡單。 請參閱 將密碼和其他敏感性資料部署至 ASP.NET 和 Azure 的最佳做法

  6. 將資料傳輸至 SMS 提供者的實作

    SmsServiceApp_Start\IdentityConfig.cs檔案中設定 類別。

    視使用的 SMS 提供者而定,會啟用 TwilioASPSMS 區段:

    public class SmsService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            // Twilio Begin
            //var accountSid = ConfigurationManager.AppSettings["SMSAccountIdentification"];
            //var authToken = ConfigurationManager.AppSettings["SMSAccountPassword"];
            //var fromNumber = ConfigurationManager.AppSettings["SMSAccountFrom"];
    
            //TwilioClient.Init(accountSid, authToken);
    
            //MessageResource result = MessageResource.Create(
                //new PhoneNumber(message.Destination),
                //from: new PhoneNumber(fromNumber),
               //body: message.Body
            //);
    
            ////Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
             //Trace.TraceInformation(result.Status.ToString());
            ////Twilio doesn't currently have an async API, so return success.
             //return Task.FromResult(0);    
            // Twilio End
    
            // ASPSMS Begin 
            // var soapSms = new MvcPWx.ASPSMSX2.ASPSMSX2SoapClient("ASPSMSX2Soap");
            // soapSms.SendSimpleTextSMS(
            //   System.Configuration.ConfigurationManager.AppSettings["SMSAccountIdentification"],
            //   System.Configuration.ConfigurationManager.AppSettings["SMSAccountPassword"],
            //   message.Destination,
            //   System.Configuration.ConfigurationManager.AppSettings["SMSAccountFrom"],
            //   message.Body);
            // soapSms.Close();
            // return Task.FromResult(0);
            // ASPSMS End
        }
    }
    
  7. 更新 Views\Manage\Index.cshtml Razor 檢視: (注意:不要只是移除結束程式碼中的批註,請使用下列程式碼。)

    @model MvcPWy.Models.IndexViewModel
    @{
       ViewBag.Title = "Manage";
    }
    <h2>@ViewBag.Title.</h2>
    <p class="text-success">@ViewBag.StatusMessage</p>
    <div>
       <h4>Change your account settings</h4>
       <hr />
       <dl class="dl-horizontal">
          <dt>Password:</dt>
          <dd>
             [
             @if (Model.HasPassword)
             {
                @Html.ActionLink("Change your password", "ChangePassword")
             }
             else
             {
                @Html.ActionLink("Create", "SetPassword")
             }
             ]
          </dd>
          <dt>External Logins:</dt>
          <dd>
             @Model.Logins.Count [
             @Html.ActionLink("Manage", "ManageLogins") ]
          </dd>
            <dt>Phone Number:</dt>
          <dd>
             @(Model.PhoneNumber ?? "None") [
             @if (Model.PhoneNumber != null)
             {
                @Html.ActionLink("Change", "AddPhoneNumber")
                @: &nbsp;|&nbsp;
                @Html.ActionLink("Remove", "RemovePhoneNumber")
             }
             else
             {
                @Html.ActionLink("Add", "AddPhoneNumber")
             }
             ]
          </dd>
          <dt>Two-Factor Authentication:</dt> 
          <dd>
             @if (Model.TwoFactor)
             {
                using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                   @Html.AntiForgeryToken()
                   <text>Enabled
                      <input type="submit" value="Disable" class="btn btn-link" />
                   </text>
                }
             }
             else
             {
                using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                {
                   @Html.AntiForgeryToken()
                   <text>Disabled
                      <input type="submit" value="Enable" class="btn btn-link" />
                   </text>
                }
             }
          </dd>
       </dl>
    </div>
    
  8. EnableTwoFactorAuthentication確認 中的 ManageControllerDisableTwoFactorAuthentication 動作方法具有[ValidateAntiForgeryToken]屬性:

    //
    // POST: /Manage/EnableTwoFactorAuthentication
    [HttpPost,ValidateAntiForgeryToken]
    public async Task<ActionResult> EnableTwoFactorAuthentication()
    {
        await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (user != null)
        {
            await SignInAsync(user, isPersistent: false);
        }
        return RedirectToAction("Index", "Manage");
    }
    //
    // POST: /Manage/DisableTwoFactorAuthentication
    [HttpPost, ValidateAntiForgeryToken]
    public async Task<ActionResult> DisableTwoFactorAuthentication()
    {
        await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false);
        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (user != null)
        {
            await SignInAsync(user, isPersistent: false);
        }
        return RedirectToAction("Index", "Manage");
    }
    
  9. 執行應用程式,並使用您先前註冊的帳戶登入。

  10. 按一下您的 [使用者識別碼],這會啟動 Index 控制器中的 Manage 動作方法。
    顯示 S P 點 NET 應用程式首頁的螢幕擷取畫面。醒目提示 [範例使用者識別碼]。

  11. 按一下 [新增]。
    顯示 [S P 點 NET 應用程式帳戶設定] 頁面的螢幕擷取畫面。[電話號碼] 區段旁的 [無新增] 會反白顯示。

  12. AddPhoneNumber動作方法會顯示對話方塊,以輸入可接收 SMS 訊息的電話號碼。

    // GET: /Account/AddPhoneNumber
    public ActionResult AddPhoneNumber()
    {
       return View();
    }
    

    顯示 [新增電話號碼] 頁面的 S P 點 NET 應用程式螢幕擷取畫面。範例電話號碼會填入其下方的 [傳送驗證碼] 按鈕。

  13. 幾秒鐘後,您會收到含有驗證碼的簡訊。 輸入它,然後按 [提交]。
    S P 點 NET 應用程式 [新增電話號碼] 頁面的螢幕擷取畫面,其中顯示填入範例驗證碼的輸入列,以及其下方的 [提交] 按鈕。

  14. [管理] 檢視會顯示已新增您的電話號碼。

啟用雙因素驗證

在範本產生的應用程式中,您必須使用 UI 來啟用雙因素驗證 (2FA) 。 若要啟用 2FA,請按一下導覽列中 (電子郵件別名) 的使用者識別碼。

顯示 S P 點 NET 應用程式首頁的螢幕擷取畫面。已醒目提示範例使用者識別碼。

按一下 [啟用 2FA]。

顯示 [S P 點 NET 應用程式帳戶設定] 頁面的螢幕擷取畫面。Two-Factor驗證:已醒目提示 [啟用連結] 區段停用。

登出,然後重新登入。 如果您已啟用電子郵件 (請參閱 上一 個教學課程) ,您可以選取 2FA 的 SMS 或電子郵件。

顯示 [S P 點 NET] 應用程式 [傳送驗證碼] 頁面的螢幕擷取畫面。已選取顯示 [電話代碼] 和 [Email代碼] 的下拉式功能表。

[驗證代碼] 頁面隨即顯示,您可以從 SMS 或電子郵件) 輸入代碼 (。

顯示 2 FA 的 S P 點 NET 應用程式 [驗證] 頁面的螢幕擷取畫面。在範例程式碼下方,已醒目提示 [記住此瀏覽器] 的核取方塊。

按一下 [ 記住此瀏覽器 ] 核取方塊,即可免除您在使用您核取方塊的瀏覽器和裝置時,需要使用 2FA 登入。 只要惡意使用者無法存取您的裝置,啟用 2FA 並按一下 [記住此瀏覽器 ] 可提供方便的一個步驟密碼存取,同時仍保留來自非信任裝置之所有存取的強式 2FA 保護。 您可以在您定期使用的任何私人裝置上執行此動作。

本教學課程提供在新的 ASP.NET MVC 應用程式上啟用 2FA 的快速簡介。 我的教學 課程使用 SMS 和電子郵件搭配 ASP.NET 身分識別進行雙因素驗證 ,詳細說明範例背後的程式碼。

其他資源