共用方式為


ASP.NET MVC 5 應用程式使用 SMS 和電子郵件 Two-Factor 驗證

作者 Rick Anderson

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

本教學課程由 里克·安德森 撰寫(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 Forms 也支援 ASP.NET 身分識別,因此您可以遵循 Web 窗體應用程式中的類似步驟。
    顯示 [新增 A 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

    Namespace:
    ASPSMSX2

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

我們建議使用最安全的驗證選項。 如需部署至 Azure 的 .NET 應用程式,請參閱:

Azure Key Vault 和 .NET Aspire 提供最安全的方式來儲存和擷取秘密。 Azure Key Vault 是一項雲端服務,可保護加密密鑰和秘密,例如憑證、連接字串和密碼。 如需 .NET Aspire,請參閱 主機與用戶端整合間的安全通訊

請避免資源擁有者密碼憑證授權,因為:

  • 將使用者的密碼公開給用戶端。
  • 這是一個重大的安全性風險。
  • 只有在無法執行其他驗證流程時,才應該使用。

當應用程式部署至測試伺服器時,環境變數可用來將連接字串設定為測試資料庫伺服器。 環境變數通常會以純文字、未加密的文字儲存。 如果計算機或進程遭到入侵,則不受信任的合作物件可以存取環境變數。 建議您不要使用環境變數來儲存生產連接字串,因為它不是最安全的方法。

設定資料指導方針:

  • 請勿將密碼或其他敏感數據儲存在組態提供者程式代碼或純文本組態檔中。
  • 請勿在開發或測試環境中使用生產秘密。
  • 指定專案外部的密碼,以避免不小心提交到原始碼庫中。

Twilio:
從 Twilio 帳戶的 [儀錶板] 索引標籤中,複製 帳戶 SID驗證令牌

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

我們稍後會將這些值儲存在 web.config 檔案中的索引鍵 "SMSAccountIdentification""SMSAccountPassword"。 4. 指定發件人ID(SenderID)/ 起始地(Originator)

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

ASPSMS:
在 [解除鎖定發送者 功能表內,解鎖一個或多個發送者,或選擇英數字發送者(並非所有網路皆支援)。

我們稍後會將此值儲存在金鑰 內的 "SMSAccountFrom" 檔案中。 5. 將 SMS 提供者認證傳輸至應用程式

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

[!code-xml[Main](aspnet-mvc-5-app-with-sms-and-email-two-factor-authentication/samples/sample1.xml?highlight=8-10)]

> [!WARNING]
> Security - Never store sensitive data in your source code. The account and credentials are added to the code above to keep the sample simple. See [Best practices for deploying passwords and other sensitive data to ASP.NET and Azure](../../../identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure.md).
  1. 將數據傳輸至SMS服務提供商的實作

    SmsService 檔案中設定 類別。

    根據所使用的 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
        }
    }
    
  2. 更新 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>
    
  3. 確認 EnableTwoFactorAuthentication 中的 DisableTwoFactorAuthenticationManageController 動作方法具有[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");
    }
    
  4. 執行應用程式,並使用您先前註冊的帳戶登入。

  5. 按兩下您的使用者識別碼,以在 Index 控制器中啟動 Manage 動作方法。
    顯示 A S P 點 NET 應用程式首頁的螢幕快照。範例用戶 ID 被突出顯示。

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

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

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

    顯示 A S P 點 NET 應用程式 [新增電話號碼] 頁面的螢幕快照。範例電話號碼已填入,其下方有一個 [傳送驗證碼] 按鈕。

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

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

啟用雙因素驗證

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

顯示 A S P 點 NET 應用程式首頁的螢幕快照。醒目提示範例 USER I D。

按兩下 [啟用 2FA]。

顯示 [ASP.NET 應用程式帳戶設定頁面] 的螢幕快照。Two-Factor 驗證:停用,並已醒目提示 [啟用連結] 區段。

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

顯示 ASP.NET 應用程式傳送驗證碼頁面的螢幕快照。已選取顯示 [電話代碼] 和 [電子郵件代碼] 的下拉選單。

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

螢幕快照,其中顯示 A S P 點 NET 應用程式針對 2FA 的驗證頁面。在範例程式代碼底下,醒目提示記住此瀏覽器的複選框。

單擊 [記住此瀏覽器] 複選框,即可在使用這個瀏覽器和裝置時,無需使用 2FA 登入。 只要惡意使用者無法存取您的裝置,啟用 2FA 並點擊 記住此瀏覽器 會為您提供方便的一步驟密碼存取,同時仍保留對於所有來自非信任裝置的強大的2FA保護。 您可以在您經常使用的任何私人裝置上執行此動作。

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

其他資源