使用 SMS 雙因素驗證建立 ASP.NET Web Forms 應用程式 (C#)

作者 :Erik Reitan

使用 Email 和 SMS Two-Factor 驗證下載 ASP.NET Web Forms應用程式

本教學課程說明如何使用 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 通常會以電子郵件或簡訊的形式傳送給使用者。 然後,應用程式的使用者會在登入時輸入 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. 建立新的專案 ([檔案- >新增專案]) ,然後從 [新增專案] 對話方塊中選取 [.NET Framework 4.5.2 版] ASP.NET Web 應用程式範本。
  2. 從 [新增 ASP.NET 專案] 對話方塊中,選取Web Form範本。 將預設驗證保留為 個別使用者帳戶。 然後按一下 [ 確定 ] 以建立新的專案。
    [新增 A S P 點 Net 專案] 對話方塊的螢幕擷取畫面,其中顯示以藍色醒目提示的Web Form圖示。
  3. 為專案啟用安全通訊端層 (SSL) 。 Follow the steps available in the Enable SSL for the Project section of the Getting Started with Web Forms tutorial series.
  4. 在 Visual Studio 中,開啟套件管理員主控台 (Tools - >NuGet Package Manger - >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 是電子郵件通知服務。 For details about how to enable SendGrid, see the 'Hook Up SendGrid' section of the tutorial titled Create a Secure ASP.NET Web Forms App with user registration, email confirmation and password reset.

    </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. SmsServiceApp_Start\IdentityConfig.cs檔案中設定 類別,方法是以黃色醒目提示下列變更:

    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. Page_LoadManage.aspx.cs程式碼後置的處理常式中,取消批註以黃色醒目提示的程式程式碼,使其如下所示:

    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. Solution Explorer中,以滑鼠右鍵按一下Default.aspx,然後選取 [設定為起始頁]。

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

  12. 當您以使用者) 登入時 (之後,請按一下導覽列中) 的使用者識別碼 (電子郵件地址,以顯示 [ 管理帳戶 ] 頁面, (Manage.aspx) 。
    [S P 點 Net 回應瀏覽器] 視窗的螢幕擷取畫面,其中顯示醒目提示紅色矩形的使用者識別碼。

  13. 按一下 [管理帳戶] 頁面上的[電話號碼] 旁的 [新增]。
    [管理帳戶] 瀏覽器視窗的螢幕擷取畫面,其中顯示用來變更帳戶設定清單和選項連結。

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

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

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

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

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

其他資源