使用 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 應用程式
- 設定SMS和驗證系統 Two-Factor
- 為已註冊的使用者 啟用 Two-Factor 驗證
- 其他資源
建立 ASP.NET Web Forms 應用程式
從安裝並執行 Visual Studio Express 2013 for Web 或 Visual Studio 2013開始。 安裝 Visual Studio 2013 Update 3 或更高版本。 此外,您必須建立 Twilio 帳戶,如下所述。
注意
重要事項:您必須安裝 Visual Studio 2013 Update 3 或更高版本,才能完成本教學課程。
- 建立新的專案(檔案 ->新增專案),然後從 [新增專案] 對話框選取 [ASP.NET Web 應用程式] 範本和 .NET Framework 4.5.2 版。
- 從 [新增 ASP.NET 專案] 對話框中,選取 [Web Forms] 範本。 將預設驗證保留為 個別用戶帳戶。 然後,按 確定 來建立新的專案。
- 為項目啟用安全套接字層 (SSL)。 請遵循 開始使用 Web Forms 教學課程系列中的 為專案啟用 SSL 一節所提供的步驟。
- 在 Visual Studio 中,開啟 Package Manager Console (Tools ->NuGet 套件管理工具 ->Package Manager Console),然後輸入下列命令:
Install-Package Twilio
設定SMS和 Two-Factor 驗證
本教學課程使用 Twilio,但您可以使用任何 SMS 提供者。
建立 Twilio 帳戶。
從 Twilio 帳戶的 [儀錶板] 標籤中,複製 [帳戶 SID 和 驗證令牌]。 您稍後會將它們新增到您的應用程式中。
從 [號碼] 標籤,複製您的 Twilio 電話號碼。
將 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的最佳作法。
請在 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); } }
將下列
using
語句新增至 IdentityConfig.cs 檔案的開頭:using Twilio; using System.Net; using System.Configuration; using System.Diagnostics;
將 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]" /> | <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>
在 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); } } }
在 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 將不會重設為第一個值。 這可讓使用者成功選取驗證時要使用的所有選項,而不只是第一個選項。
在 [方案總管]中,以滑鼠右鍵按兩下 [Default.aspx],然後選取 [設定為起始頁] 。
藉由測試您的應用程式,請先建置應用程式(Ctrl+Shift+B),然後執行應用程式 (F5),然後選取 [註冊] 以建立新的用戶帳戶,或選取 [登入,如果使用者帳戶已註冊。
一旦您(身為使用者)登入之後,請按兩下導覽列中的 [用戶識別元](電子郵件位址),以顯示 [管理帳戶] 頁面 (Manage.aspx)。
按兩下 [管理帳戶] 頁面上
[電話號碼 旁的 [新增 ]。
新增您(作為使用者)想要接收簡訊的電話號碼,然後點擊提交 [] 按鈕。
此時,應用程式會使用來自 Web.config 的認證來連絡 Twilio。 SMS 訊息(簡訊)將會傳送至與用戶帳戶相關聯的電話。 您可以檢視 Twilio 儀錶板來確認 Twilio 訊息已傳送。幾秒鐘后,與使用者帳戶相關聯的電話將會收到包含驗證碼的簡訊。 輸入驗證碼,然後按 送出。
為已註冊的用戶啟用 Two-Factor 驗證
此時,您已為您的應用程式啟用雙因素驗證。 若要讓使用者使用雙因素驗證,他們只要使用UI來變更其設定即可。
- 身為應用程式的使用者,您可以點擊導覽列中的使用者識別元(電子郵件別名)來啟用特定帳戶的雙因素驗證,以顯示[管理帳戶]頁面。然後,點擊[啟用] 連結。
- 登出,然後重新登入。 如果您已啟用電子郵件,您可以選取SMS或電子郵件進行雙因素驗證。 如果您尚未啟用電子郵件,請參閱名為 使用使用者註冊、電子郵件確認和密碼重設建立安全 ASP.NET Web Forms 應用程式的教學課程,。
- [Two-Factor 驗證] 頁面隨即顯示,您可以在其中輸入代碼(從簡訊或電子郵件)。
勾選[記住此瀏覽器]核取方塊後,您在勾選此選項的瀏覽器和裝置上登入時,將免除使用雙因素驗證。 只要惡意使用者無法存取您的裝置,啟用雙因素驗證並點擊 記住此瀏覽器 就能為您提供便利的單步驟密碼存取,同時仍為所有來自非信任裝置的存取保留強健的雙因素驗證保護。 您可以在您經常使用的任何私人裝置上執行此動作。