共用方式為


使用 SMS Two-Factor 驗證建立 ASP.NET Web Forms 應用程式 (C#)

作者是 Erik Reitan

本教學課程說明如何使用 Two-Factor 驗證建置 ASP.NET Web Forms 應用程式。 本教學課程旨在補充名為 使用使用者註冊、電子郵件確認和密碼重設建立安全的 ASP.NET Web Forms 應用程式教學課程。 此外,本教學課程是以 Rick Anderson 的 MVC 教學課程為基礎,

介紹

本教學課程會引導您完成使用 Visual Studio 建立支援 Two-Factor 驗證 ASP.NET Web Forms 應用程式所需的步驟。 Two-Factor 驗證是額外的用戶驗證步驟。 這個額外的步驟會在登入期間產生唯一的個人標識碼(PIN)。 PIN 通常會以電子郵件或SMS訊息的形式傳送給使用者。 應用程式的用戶接著會在登入時輸入 PIN 作為額外的驗證量值。

教學任務和資訊:

建立 ASP.NET Web Forms 應用程式

從安裝並執行 Visual Studio Express 2013 for WebVisual Studio 2013開始。 安裝 Visual Studio 2013 Update 3 或更高版本。 此外,您必須建立 Twilio 帳戶,如下所述。

注意

重要事項:您必須安裝 Visual Studio 2013 Update 3 或更高版本,才能完成本教學課程。

  1. 建立新的專案(檔案 ->新增專案),然後從 [新增專案] 對話框選取 [ASP.NET Web 應用程式] 範本和 .NET Framework 4.5.2 版。
  2. 從 [新增 ASP.NET 專案] 對話框中,選取 [Web Forms] 範本。 將預設驗證保留為 個別用戶帳戶。 然後,按 確定 來建立新的專案。
    [新增 ASP.NET 專案] 對話框的螢幕快照,其中顯示藍色高亮的 Web Forms 圖示。
  3. 為項目啟用安全套接字層 (SSL)。 請遵循 開始使用 Web Forms 教學課程系列中的 為專案啟用 SSL 一節所提供的步驟。
  4. 在 Visual Studio 中,開啟 Package Manager ConsoleTools ->NuGet 套件管理工具 ->Package Manager Console),然後輸入下列命令:
    Install-Package Twilio

設定SMS和 Two-Factor 驗證

本教學課程使用 Twilio,但您可以使用任何 SMS 提供者。

  1. 建立 Twilio 帳戶。

  2. 從 Twilio 帳戶的 [儀錶板] 標籤中,複製 [帳戶 SID驗證令牌]。 您稍後會將它們新增到您的應用程式中。

  3. 從 [號碼] 標籤,複製您的 Twilio 電話號碼

  4. 將 Twilio 帳戶 SID驗證令牌電話號碼 提供給應用程式使用。 為了簡化工作,您會將這些值儲存在 web.config 檔案中。 當您部署至 Azure 時,您可以在 [網站設定] 索引標籤上的 [appSettings] 區段中安全地儲存值。此外,新增電話號碼時,只會使用號碼。
    請注意,您也可以新增 SendGrid 認證。 SendGrid 是電子郵件通知服務。 如需如何啟用 SendGrid 的詳細資訊,請參閱標題為 建立具有使用者註冊、電子郵件確認和密碼重設的安全 ASP.NET Web Forms 應用程式教學課程的<掛接 SendGrid>一節。

    </connectionStrings>
      <appSettings>
        <!-- SendGrid Credentials-->    
        <add key="emailServiceUserName" value="[EmailServiceAccountUserName]" />
        <add key="emailServicePassword" value="[EmailServiceAccountPassword]" />
        <!-- Twilio Credentials-->
        <add key="SMSSID" value="[SMSServiceAccountSID]" />
        <add key="SMSAuthToken" value="[SMSServiceAuthorizationToken]" />
        <add key="SMSPhoneNumber" value="+[SMSPhoneNumber]" />    
      </appSettings>
      <system.web>
    

    警告

    安全性 - 永遠不要將敏感數據儲存在您的原始程式碼中。 在此範例中,帳戶和認證會儲存在 Web.config 檔案的 appSettings 區段中。 在 Azure 上,您可以在 Azure 入口網站的 [設定] 索引標籤上安全地儲存這些值。 如需相關信息,請參閱 Rick Anderson 主題,標題為 將密碼和其他敏感數據部署至 ASP.NET 和 Azure的最佳作法。

  5. 請在 App_Start\IdentityConfig.cs 檔案中,配置 SmsService 類別,並以黃色標記下列變更進行確認:

    public class SmsService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            var Twilio = new TwilioRestClient(
               ConfigurationManager.AppSettings["SMSSID"],
               ConfigurationManager.AppSettings["SMSAuthToken"]
            );
            var result = Twilio.SendMessage(
                ConfigurationManager.AppSettings["SMSPhoneNumber"],
               message.Destination, message.Body);
    
            // Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
            Trace.TraceInformation(result.Status);
    
            // Twilio doesn't currently have an async API, so return success.
            return Task.FromResult(0);
        }
    }
    
  6. 將下列 using 語句新增至 IdentityConfig.cs 檔案的開頭:

    using Twilio;
    using System.Net;
    using System.Configuration;
    using System.Diagnostics;
    
  7. Account/Manage.aspx 檔案中以黃色標示的行刪除,進行更新:

    <%@ Page Title="Manage Account" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Manage.aspx.cs" Inherits="WebFormsTwoFactor.Account.Manage" %>
    
    <%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %>
    
    <asp:Content ContentPlaceHolderID="MainContent" runat="server">
        <h2><%: Title %>.</h2>
    
        <div>
            <asp:PlaceHolder runat="server" ID="successMessage" Visible="false" ViewStateMode="Disabled">
                <p class="text-success"><%: SuccessMessage %></p>
            </asp:PlaceHolder>
        </div>
    
        <div class="row">
            <div class="col-md-12">
                <div class="form-horizontal">
                    <h4>Change your account settings</h4>
                    <hr />
                    <dl class="dl-horizontal">
                        <dt>Password:</dt>
                        <dd>
                            <asp:HyperLink NavigateUrl="/Account/ManagePassword" Text="[Change]" Visible="false" ID="ChangePassword" runat="server" />
                            <asp:HyperLink NavigateUrl="/Account/ManagePassword" Text="[Create]" Visible="false" ID="CreatePassword" runat="server" />
                        </dd>
                        <dt>External Logins:</dt>
                        <dd><%: LoginsCount %>
                            <asp:HyperLink NavigateUrl="/Account/ManageLogins" Text="[Manage]" runat="server" />
    
                        </dd>
                        <%--
                            Phone Numbers can used as a second factor of verification in a two-factor authentication system.
                            See <a href="https://go.microsoft.com/fwlink/?LinkId=313242">this article</a>
                            for details on setting up this ASP.NET application to support two-factor authentication using SMS.
                            Uncomment the following block after you have set up two-factor authentication
                        --%>
    
                        <dt>Phone Number:</dt>
                        <%--
                        <% if (HasPhoneNumber)
                           { %>
                        <dd>
                            <asp:HyperLink NavigateUrl="/Account/AddPhoneNumber" runat="server" Text="[Add]" />
                        </dd>
                        <% }
                           else
                           { %>
                        <dd>
                            <asp:Label Text="" ID="PhoneNumber" runat="server" />
                            <asp:HyperLink NavigateUrl="/Account/AddPhoneNumber" runat="server" Text="[Change]" /> &nbsp;|&nbsp;
                            <asp:LinkButton Text="[Remove]" OnClick="RemovePhone_Click" runat="server" />
                        </dd>
                        <% } %>
                        --%>
    
                        <dt>Two-Factor Authentication:</dt>
                        <dd>
                            <p>
                                There are no two-factor authentication providers configured. See <a href="https://go.microsoft.com/fwlink/?LinkId=313242">this article</a>
                                for details on setting up this ASP.NET application to support two-factor authentication.
                            </p>
                            <% if (TwoFactorEnabled)
                              { %> 
                            <%--
                            Enabled
                            <asp:LinkButton Text="[Disable]" runat="server" CommandArgument="false" OnClick="TwoFactorDisable_Click" />
                            --%>
                            <% }
                              else
                              { %> 
                            <%--
                            Disabled
                            <asp:LinkButton Text="[Enable]" CommandArgument="true" OnClick="TwoFactorEnable_Click" runat="server" />
                            --%>
                            <% } %>
                        </dd>
                    </dl>
                </div>
            </div>
        </div>
    </asp:Content>
    
  8. Manage.aspx.cs 程式代碼後置的 Page_Load 處理程式中,取消批注以黃色醒目提示的程式代碼行,使其如下所示:

    protected void Page_Load()
    {
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
    
        HasPhoneNumber = String.IsNullOrEmpty(manager.GetPhoneNumber(User.Identity.GetUserId()));
    
        // Enable this after setting up two-factor authentientication
        PhoneNumber.Text = manager.GetPhoneNumber(User.Identity.GetUserId()) ?? String.Empty;
    
        TwoFactorEnabled = manager.GetTwoFactorEnabled(User.Identity.GetUserId());
    
        LoginsCount = manager.GetLogins(User.Identity.GetUserId()).Count;
    
        var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
    
        if (!IsPostBack)
        {
            // Determine the sections to render
            if (HasPassword(manager))
            {
                ChangePassword.Visible = true;
            }
            else
            {
                CreatePassword.Visible = true;
                ChangePassword.Visible = false;
            }
    
            // Render success message
            var message = Request.QueryString["m"];
            if (message != null)
            {
                // Strip the query string from action
                Form.Action = ResolveUrl("~/Account/Manage");
    
                SuccessMessage =
                    message == "ChangePwdSuccess" ? "Your password has been changed."
                    : message == "SetPwdSuccess" ? "Your password has been set."
                    : message == "RemoveLoginSuccess" ? "The account was removed."
                    : message == "AddPhoneNumberSuccess" ? "Phone number has been added"
                    : message == "RemovePhoneNumberSuccess" ? "Phone number was removed"
                    : String.Empty;
                successMessage.Visible = !String.IsNullOrEmpty(SuccessMessage);
            }
        }
    }
    
  9. Account/TwoFactorAuthenticationSignIn.aspx.cs的後置代碼中,新增以下以黃色醒目提示的程式碼來更新 Page_Load 處理程序:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            var userId = signinManager.GetVerifiedUserId<ApplicationUser, string>();
            if (userId == null)
            {
                Response.Redirect("/Account/Error", true);
            }
            var userFactors = manager.GetValidTwoFactorProviders(userId);
            Providers.DataSource = userFactors.Select(x => x).ToList();
            Providers.DataBind();
        }
    }
    

    藉由進行上述程式代碼變更,包含驗證選項的 「提供者」DropDownList 將不會重設為第一個值。 這可讓使用者成功選取驗證時要使用的所有選項,而不只是第一個選項。

  10. [方案總管]中,以滑鼠右鍵按兩下 [Default.aspx],然後選取 [設定為起始頁]

  11. 藉由測試您的應用程式,請先建置應用程式(Ctrl+Shift+B),然後執行應用程式 (F5),然後選取 [註冊] 以建立新的用戶帳戶,或選取 [登入,如果使用者帳戶已註冊。

  12. 一旦您(身為使用者)登入之後,請按兩下導覽列中的 [用戶識別元](電子郵件位址),以顯示 [管理帳戶] 頁面 (Manage.aspx)。
    A S P 點網回應瀏覽器視窗的螢幕截圖,顯示以紅色矩形框標示的使用者 ID。

  13. 按兩下 [管理帳戶] 頁面上 [電話號碼 旁的 [新增 ]。
    [管理帳戶] 瀏覽器視窗的螢幕快照,其中顯示帳戶設定清單和選項連結以變更它們。

  14. 新增您(作為使用者)想要接收簡訊的電話號碼,然後點擊提交 [] 按鈕。
    [電話號碼] 瀏覽器視窗的螢幕快照,其中顯示 [電話號碼] 字段,其中包含輸入的電話號碼值和 [提交] 按鈕。
    此時,應用程式會使用來自 Web.config 的認證來連絡 Twilio。 SMS 訊息(簡訊)將會傳送至與用戶帳戶相關聯的電話。 您可以檢視 Twilio 儀錶板來確認 Twilio 訊息已傳送。

  15. 幾秒鐘后,與使用者帳戶相關聯的電話將會收到包含驗證碼的簡訊。 輸入驗證碼,然後按 送出
    [驗證電話號碼] 瀏覽器視窗的螢幕快照,其中顯示 [代碼] 字段與輸入的驗證碼和 [提交] 按鈕。

為已註冊的用戶啟用 Two-Factor 驗證

此時,您已為您的應用程式啟用雙因素驗證。 若要讓使用者使用雙因素驗證,他們只要使用UI來變更其設定即可。

  1. 身為應用程式的使用者,您可以點擊導覽列中的使用者識別元(電子郵件別名)來啟用特定帳戶的雙因素驗證,以顯示[管理帳戶]頁面。然後,點擊[啟用] 連結。[管理帳戶]瀏覽器視窗的螢幕快照,其中顯示以紅色醒目提示Two-Factor 驗證相關聯的[啟用]連結。
  2. 登出,然後重新登入。 如果您已啟用電子郵件,您可以選取SMS或電子郵件進行雙因素驗證。 如果您尚未啟用電子郵件,請參閱名為 使用使用者註冊、電子郵件確認和密碼重設建立安全 ASP.NET Web Forms 應用程式的教學課程,[Two-Factor 驗證瀏覽器] 視窗的螢幕快照,其中顯示 [選取 Two-Factor 驗證提供者] 下拉式清單。
  3. [Two-Factor 驗證] 頁面隨即顯示,您可以在其中輸入代碼(從簡訊或電子郵件)。[Two-Factor 驗證瀏覽器] 視窗的螢幕快照,其中顯示 [程序代碼] 欄位與輸入的驗證碼和 [提交] 按鈕。
    勾選[記住此瀏覽器]核取方塊後,您在勾選此選項的瀏覽器和裝置上登入時,將免除使用雙因素驗證。 只要惡意使用者無法存取您的裝置,啟用雙因素驗證並點擊 記住此瀏覽器 就能為您提供便利的單步驟密碼存取,同時仍為所有來自非信任裝置的存取保留強健的雙因素驗證保護。 您可以在您經常使用的任何私人裝置上執行此動作。

其他資源