Udostępnij za pośrednictwem


ASP.NET MVC 5 aplikacja z wiadomościami SMS i Two-Factor uwierzytelnianiem e-mailem

autor: Rick Anderson

W tym samouczku pokazano, jak utworzyć aplikację internetową ASP.NET MVC 5 przy użyciu uwierzytelniania Two-Factor. Przed kontynuowaniem należy ukończyć Utwórz bezpieczną aplikację internetową ASP.NET MVC 5 z logowaniem, potwierdzeniem e-maila i resetowaniem hasła. Ukończoną aplikację można pobrać tutaj. Pobieranie zawiera pomocników debugowania, które umożliwiają testowanie potwierdzenia wiadomości e-mail i wiadomości SMS bez konfigurowania dostawcy poczty e-mail lub programu SMS.

Ten samouczek został napisany przez Rick Anderson ( Twitter: @RickAndMSFT ).

Tworzenie aplikacji MVC ASP.NET

Zacznij od zainstalowania i uruchomienia programu Visual Studio Express 2013 dla sieci Web lub późniejszej wersji.

Notatka

Ostrzeżenie: Przed kontynuowaniem należy ukończyć Utwórz bezpieczną aplikację internetową MVC 5 ASP.NET z logowaniem, potwierdzeniem wiadomości e-mail i resetowaniem hasła. Aby ukończyć ten samouczek, musisz zainstalować program Visual Studio 2013 Update 3 lub nowszy.

  1. Utwórz nowy projekt ASP.NET sieci Web i wybierz szablon MVC. Usługa Web Forms obsługuje również ASP.NET Identity, dzięki czemu można wykonać podobne kroki w aplikacji formularzy internetowych.
    Zrzut ekranu przedstawiający okno
  2. Pozostaw domyślne uwierzytelnianie indywidualne konta użytkowników. Jeśli chcesz hostować aplikację na platformie Azure, zaznacz pole wyboru. W dalszej części samouczka wdrożymy na platformie Azure. Możesz otworzyć bezpłatne konto platformy Azure.
  3. Ustaw projekt na używanieSSL.

Konfigurowanie wiadomości SMS na potrzeby uwierzytelniania dwuskładnikowego

Ten samouczek zawiera instrukcje dotyczące korzystania z usługi Twilio lub ASPSMS, ale możesz użyć dowolnego innego dostawcy programu SMS.

  1. tworzenie konta użytkownika przy użyciu dostawcy programu SMS

    Utwórz konto Twilio lub konto ASPSMS.

  2. Instalowanie dodatkowych pakietów lub dodawanie odwołań do usług

    Twilio:
    W konsoli menedżera pakietów wprowadź następujące polecenie:
    Install-Package Twilio

    ASPSMS:
    Należy dodać następujące odwołanie do usługi:

    Zrzut ekranu przedstawiający okno Dodaj odwołanie do usługi. Paski wprowadzania Adres i Przestrzeń nazw są wyróżnione.

    Adres:
    https://webservice.aspsms.com/aspsmsx2.asmx?WSDL

    Namespace:
    ASPSMSX2

  3. ustalenie poświadczeń użytkownika dostawcy programu SMS

Zalecamy użycie najbezpieczniejszej opcji bezpiecznego uwierzytelniania. W przypadku aplikacji platformy .NET wdrożonych na platformie Azure zobacz:

Azure Key Vault i .NET Aspire zapewniają najbezpieczniejszy sposób przechowywania i pobierania tajnych informacji. Azure Key Vault to usługa w chmurze, która chroni klucze szyfrowania i wpisy tajne, takie jak certyfikaty, parametry połączenia i hasła. Aby zapoznać się z programem .NET Aspire, sprawdź Bezpieczna komunikacja między hostingiem a integracjami klientów.

Unikaj metody przyznawania dostępu za pomocą hasła właściciela zasobu, ponieważ:

  • Uwidacznia hasło użytkownika klientowi.
  • Jest istotnym zagrożeniem bezpieczeństwa.
  • Należy używać tylko wtedy, gdy inne przepływy uwierzytelniania nie są możliwe.

Po wdrożeniu aplikacji na serwerze testowym zmienna środowiskowa może służyć do ustawiania parametrów połączenia na testowy serwer bazy danych. Zmienne środowiskowe są zwykle przechowywane w postaci zwykłego, niezaszyfrowanego tekstu. W przypadku naruszenia zabezpieczeń maszyny lub procesu zmienne środowiskowe mogą być dostępne dla niezaufanych stron. Odradzamy używanie zmiennych środowiskowych do przechowywania parametrów połączenia produkcyjnego, ponieważ nie jest to najbezpieczniejsze podejście.

Wytyczne dotyczące danych konfiguracji:

  • Nigdy nie przechowuj haseł ani innych poufnych danych w kodzie dostawcy konfiguracji ani w plikach konfiguracji zwykłego tekstu.
  • Nie używaj tajemnic produkcyjnych w środowiskach programistycznych ani testowych.
  • Określ tajne dane poza projektem, aby nie mogły zostać przypadkowo umieszczone w repozytorium kodu źródłowego.

Twilio:
Na karcie Dashboard konta Twilio skopiuj identyfikator SID konta i token uwierzytelniania .

ASPSMS:
W ustawieniach konta przejdź do klucza użytkownika i skopiuj go razem z własnym hasłem.

Później zapiszemy te wartości w pliku web.config w kluczach "SMSAccountIdentification" i "SMSAccountPassword". 4. określanie identyfikatora nadawcy/

Twilio:
Na karcie Numery skopiuj numer telefonu usługi Twilio.

ASPSMS:
W Odblokuj elementy rozpoczynające Menu odblokuj co najmniej jeden element rozpoczynający lub wybierz element rozpoczynający alfanumeryczny (nieobsługiwany przez wszystkie sieci).

Później zapiszemy tę wartość w pliku web.config w kluczu "SMSAccountFrom". 5. Przenoszenie poświadczeń dostawcy SMS do aplikacji

Udostępnij poświadczenia i numer telefonu nadawcy aplikacji. Aby zachować prostotę, zapiszemy te wartości w pliku web.config. Podczas wdrażania na platformie Azure możemy bezpiecznie przechowywać wartości w ustawieniach aplikacji na karcie Konfigurowanie witryny internetowej.

[!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. Implementacja transferu danych do dostawcy programu SMS

    Skonfiguruj klasę SmsService w pliku App_Start\IdentityConfig.cs.

    W zależności od używanego dostawcy SMS aktywuj sekcję Twilio lub ASPSMS.

    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. Zaktualizuj widok Views\Manage\Index.cshtml Razor: (uwaga: nie usuwaj komentarzy w istniejącym kodzie, użyj poniższego kodu).

    @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. Sprawdź, czy metody akcji EnableTwoFactorAuthentication i DisableTwoFactorAuthentication w ManageController mają atrybut[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. Uruchom aplikację i zaloguj się przy użyciu wcześniej zarejestrowanego konta.

  5. Kliknij swój identyfikator użytkownika, co aktywuje metodę akcji Index w kontrolerze Manage.
    Zrzut ekranu przedstawiający stronę główną aplikacji A S P dot NET. Wyróżniono przykładowy USER ID.

  6. Kliknij przycisk Dodaj.
    Zrzut ekranu przedstawiający stronę Ustawienia konta aplikacji S P dot NET. Opcja Brak dodaj obok sekcji Numer telefonu jest wyróżniona.

  7. Metoda akcji AddPhoneNumber wyświetla okno dialogowe, aby wprowadzić numer telefonu, który może odbierać wiadomości SMS.

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

    Zrzut ekranu przedstawiający aplikację A S P dot NET Dodaj numer telefonu. Poniżej znajduje się przykładowy numer telefonu z przyciskiem Wyślij kod weryfikacyjny.

  8. W ciągu kilku sekund otrzymasz wiadomość SMS z kodem weryfikacyjnym. Wprowadź go i naciśnij Prześlij.
    Zrzut ekranu strony aplikacji A S P dot NET Dodawanie numeru telefonu pokazujący pole tekstowe wypełnione przykładowym kodem weryfikacyjnym i przycisk Prześlij poniżej.

  9. Widok Zarządzaj pokazuje, że numer telefonu został dodany.

Włączanie uwierzytelniania dwuskładnikowego

W aplikacji wygenerowanej na podstawie szablonu należy użyć interfejsu użytkownika, aby włączyć uwierzytelnianie dwuskładnikowe (2FA). Aby włączyć uwierzytelnianie 2FA, kliknij swój identyfikator użytkownika (alias e-mail) na pasku nawigacyjnym.

Zrzut ekranu przedstawiający stronę główną aplikacji A S P dot NET. Wyróżniono przykładowy element USER ID.

Kliknij pozycję Włącz uwierzytelnianie 2FA.

Zrzut ekranu przedstawiający stronę Ustawienia konta aplikacji ASP.NET. Two-Factor Uwierzytelnianie: wyłączone z wyróżnioną sekcją z linkiem Włącz.

Wyloguj się, a następnie zaloguj się ponownie. Jeśli masz włączoną opcję e-mail (zobacz mój poprzedni samouczek ), możesz wybrać wiadomość SMS lub e-mail dla uwierzytelniania dwuskładnikowego.

Zrzut ekranu przedstawiający stronę wysyłania kodu weryfikacyjnego aplikacji A S P dot NET. Wybrano menu rozwijane pokazujące kod telefonu i kod e-mail.

Zostanie wyświetlona strona Weryfikowanie kodu, na której można wprowadzić kod (z wiadomości SMS lub wiadomości e-mail).

Zrzut ekranu przedstawiający stronę weryfikacji aplikacji ASP.NET dla 2FA. Poniżej przykładowego kodu znajduje się pole wyboru z wyróżnioną opcją

Zaznaczenie pola wyboru Zapamiętaj tę przeglądarkę spowoduje, że nie będzie wymagane użycie dwuetapowego uwierzytelniania (2FA) podczas logowania się za pomocą przeglądarki i urządzenia, w którym zaznaczono to pole. Tak długo, jak złośliwi użytkownicy nie mogą uzyskać dostępu do urządzenia, włączenie uwierzytelniania 2FA i kliknięcie Zapamiętaj tę przeglądarkę zapewni wygodny dostęp za pomocą hasła jednoetapowego, zachowując jednocześnie silną ochronę 2FA dla całego dostępu z urządzeń niezaufanych. Można to zrobić na dowolnym urządzeniu prywatnym, którego regularnie używasz.

Ten samouczek zawiera krótkie wprowadzenie do włączania uwierzytelniania 2FA w nowej aplikacji MVC ASP.NET. Mój samouczek uwierzytelnianie dwuskładnikowe przy użyciu wiadomości SMS i poczty e-mail z ASP.NET Identity zawiera szczegółowe informacje na temat kodu stojącego za przykładem.

Dodatkowe zasoby