Создание приложения ASP.NET MVC 5 с единым входом с помощью учетных данных Facebook, Twitter, LinkedIn и Google OAuth2 (C#)

Рик Андерсон

В этом руководстве показано, как создать веб-приложение ASP.NET MVC 5, которое позволяет пользователям выполнять вход с помощью OAuth 2.0 с учетными данными внешнего поставщика проверки подлинности, например Facebook, Twitter, LinkedIn, Майкрософт или Google. Для простоты в этом руководстве основное внимание уделяется работе с учетными данными facebook и Google.

Включение этих учетных данных на веб-сайтах дает значительное преимущество, так как у миллионов пользователей уже есть учетные записи этих внешних поставщиков. Эти пользователи могут быть более склонны зарегистрироваться на вашем сайте, если им не нужно создавать и запоминать новый набор учетных данных.

См. также ASP.NET приложение MVC 5 с помощью SMS и электронной почты Two-Factor аутентификации.

В этом руководстве также показано, как добавить данные профиля для пользователя и как использовать API членства для добавления ролей. Это руководство было написано Рик Андерсон (Rick Anderson ) (Пожалуйста, следите за мной в Twitter: @RickAndMSFT ).

Приступая к работе

Начните с установки и запуска Visual Studio Express 2013 для Web или Visual Studio 2013. Установите Visual Studio 2013 с обновлением 3 или более поздней версии.

Примечание

Для использования Google OAuth 2 и локальной отладки без предупреждений SSL необходимо установить Visual Studio 2013 с обновлением 3 или более поздней версии.

Щелкните Создать проект на начальной странице или в меню выберите Файл, а затем Новый проект.

Снимок экрана: начальная страница Visual Studio.

Создание первого приложения

Щелкните Новый проект, выберите Visual C# слева, Затем — Интернет , а затем — ASP.NET веб-приложение. Присвойте проекту имя MvcAuth и нажмите кнопку ОК.

Снимок экрана: страница меню

В диалоговом окне Новый проект ASP.NET щелкните MVC. Если для параметра Проверка подлинности используется не отдельные учетные записи пользователей, нажмите кнопку Изменить проверку подлинности и выберите Учетные записи отдельных пользователей. Установив флажок Узел в облаке, приложение будет очень легко разместить в Azure.

Снимок экрана, на котором показано диалоговое окно

Если вы выбрали Узел в облаке, завершите диалоговое окно настройки.

Снимок экрана: диалоговое окно

Использование NuGet для обновления до последней версии ПО промежуточного слоя OWIN

Используйте диспетчер пакетов NuGet для обновления ПО промежуточного слоя OWIN. Выберите Обновления в меню слева. Вы можете нажать кнопку Обновить все или найти только пакеты OWIN (как показано на следующем рисунке):

Снимок экрана: диалоговое окно

На рисунке ниже показаны только пакеты OWIN:

Снимок экрана: диалоговое окно

В консоли диспетчера пакетов (PMC) можно ввести Update-Package команду , которая обновит все пакеты.

Нажмите клавишу F5 или CTRL+F5 , чтобы запустить приложение. На рисунке ниже указан номер порта 1234. При запуске приложения вы увидите другой номер порта.

В зависимости от размера окна браузера может потребоваться щелкнуть значок навигации, чтобы просмотреть ссылки Главная, О программе, Контакт, Регистрация и Вход .

Снимок экрана, на котором показана домашняя страница My A S P.NET .NET. Выделен значок навигации.
Снимок экрана, на котором показана домашняя страница My A S P.NET .NET. Выделен и выбран значок навигации, в котором отображается раскрывающееся меню со ссылками навигации.

Настройка SSL в проекте

Чтобы подключиться к таким поставщикам проверки подлинности, как Google и Facebook, необходимо настроить IIS-Express для использования SSL. Важно продолжать использовать SSL после входа и не возвращаться к HTTP. Файл cookie для входа так же секретный, как ваше имя пользователя и пароль, и без использования SSL вы отправляете его в формате ясного текста по сети. Кроме того, вы уже успели выполнить подтверждение и защитить канал (это основная часть того, что делает HTTPS медленнее, чем HTTP) перед запуском конвейера MVC, поэтому перенаправление обратно на HTTP после входа в систему не ускорит текущий запрос или будущие запросы.

  1. В Обозреватель решений щелкните проект MvcAuth.

  2. Нажмите клавишу F4, чтобы отобразить свойства проекта. Кроме того, в меню Вид можно выбрать Окно свойств.

  3. Измените значение SSL Enabled на True.

    Снимок экрана: Обозреватель решений свойства проекта для проекта проверки подлинности M v c. Выделены значения S SS L Enabled True и SS L U R L.

  4. Скопируйте URL-адрес SSL (который будет иметь значение https://localhost:44300/ , если вы не создали другие проекты SSL).

  5. В Обозреватель решений щелкните правой кнопкой мыши проект MvcAuth и выберите Свойства.

  6. Выберите вкладку Интернет и вставьте URL-адрес SSL в поле Url-адрес проекта . Сохраните файл (Ctl+S). Этот URL-адрес понадобится для настройки приложений проверки подлинности Facebook и Google.

    Снимок экрана: страница свойств проекта M v c Auth. Выделены вкладка Веб в меню слева и url-адрес SS L, вставленный в поле Project U R L ( Проект).

  7. Добавьте атрибут RequireHttps в контроллер, Home чтобы требовать, чтобы все запросы использовали ПРОТОКОЛ HTTPS. Более безопасный подход заключается в добавлении фильтра RequireHttps в приложение. См. раздел "Защита приложения с помощью SSL и атрибута авторизации" в моем руководстве Создание приложения ASP.NET MVC с проверкой подлинности и базой данных SQL и развертывание в Служба приложений Azure. Часть контроллера Home показана ниже.

    [RequireHttps]
    public class HomeController : Controller
    {
       public ActionResult Index()
       {
          return View();
       }
    
  8. Для запуска приложения нажмите сочетание клавиш CTRL+F5. Если вы установили сертификат ранее, можно пропустить оставшуюся часть этого раздела и перейти к разделу Создание приложения Google для OAuth 2 и подключение приложения к проекту. В противном случае следуйте инструкциям, чтобы доверять самозаверяющим сертификату, созданному IIS Express.

    Снимок экрана: диалоговое окно Visual Studio с запросом на выбор того, следует ли доверять сертификату IS Express SL.

  9. Прочтите диалоговое окно Предупреждение системы безопасности и нажмите кнопку Да , если вы хотите установить сертификат, представляющий localhost.

    Снимок экрана: диалоговое окно

  10. В IE откроется Главная страница без предупреждений SSL.

    Снимок экрана, на котором показана домашняя страница My AS P.NET home (Домашняя страница My AS P) без предупреждений SS L.

  11. Google Chrome также принимает сертификат и отображает содержимое HTTPS без предупреждения. Firefox использует собственное хранилище сертификатов, поэтому отображает предупреждение. Для нашего приложения вы можете безопасно щелкнуть Я понимаю риски.

    Снимок экрана: приложение My A S P dot NET, работающее в Firefox. Страница предупреждения о недоверенном подключении запрашивает у пользователя, следует ли принять приложение и продолжить.

Создание приложения Google для OAuth 2 и подключение приложения к проекту

Предупреждение

Текущие инструкции по Google OAuth см. в разделе Настройка проверки подлинности Google в ASP.NET Core.

  1. Перейдите к Консоли разработчиков Google.

  2. Если вы еще не создали проект, выберите Учетные данные на вкладке слева, а затем щелкните Создать.

  3. На вкладке слева щелкните Учетные данные.

  4. Щелкните Создать учетные данные , а затем идентификатор клиента OAuth.

    1. В диалоговом окне Создание идентификатора клиента оставьте веб-приложение по умолчанию для типа приложения.
    2. Задайте для авторизованного источника JavaScript URL-адрес SSL, который вы использовали выше (https://localhost:44300/ если вы не создали другие проекты SSL).
    3. Задайте для параметра Авторизованный URI перенаправления значение:
      https://localhost:44300/signin-google
  5. Щелкните пункт меню OAuth Consent (Согласие OAuth), а затем укажите адрес электронной почты и название продукта. После заполнения формы нажмите кнопку Сохранить.

  6. Щелкните пункт меню Библиотека, найдите API Google+, щелкните его и нажмите кнопку Включить.

    Снимок экрана: список результатов поиска. Выделен результат поиска Google plus A P I.

    На рисунке ниже показаны включенные API.

    Снимок экрана, на котором показана страница Консоли разработчиков Google со списком включенных API. P I отображается как включенный, если рядом с ним отображается зеленая кнопка ВКЛЮЧЕНО.

  7. В диспетчере API Google перейдите на вкладку Учетные данные , чтобы получить идентификатор клиента. Скачайте, чтобы сохранить JSON-файл с секретами приложения. Скопируйте и вставьте ClientId и ClientSecret в UseGoogleAuthentication метод, найденный в файле Startup.Auth.cs в папке App_Start . Значения ClientId и ClientSecret , показанные ниже, являются примерами и не работают.

    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    
        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
        
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");
    
        //app.UseTwitterAuthentication(
        //   consumerKey: "",
        //   consumerSecret: "");
    
        //app.UseFacebookAuthentication(
        //   appId: "",
        //   appSecret: "");
    
        app.UseGoogleAuthentication(
             clientId: "000-000.apps.googleusercontent.com",
             clientSecret: "00000000000");
    }
    

    Предупреждение

    Безопасность— никогда не сохраняйте конфиденциальные данные в исходном коде. Учетная запись и учетные данные добавляются в приведенный выше код для простоты примера. Ознакомьтесь с рекомендациями по развертыванию паролей и других конфиденциальных данных в ASP.NET и Служба приложений Azure.

  8. Нажмите клавиши CTRL+F5 , чтобы выполнить сборку и запуск приложения. Щелкните ссылку Войти в систему .

    Снимок экрана, на котором показана домашняя страница My A S P.NET .NET. Выделены кнопка Навигация и ссылка Вход.

  9. В разделе Использовать другую службу для входа щелкнитеGoogle.

    Снимок экрана, на котором показана страница My A S P dot NET Log in (Вход в NET). Выделены диалоговое окно

    Примечание

    Если вы пропустите любой из описанных выше шагов, вы получите ошибку HTTP 401. Проверьте описанные выше действия. Если вы пропустили обязательный параметр (например , название продукта), добавьте отсутствующий элемент и сохраните его; Проверка подлинности может занять несколько минут.

  10. Вы будете перенаправлены на сайт Google, где введете свои учетные данные.

    Снимок экрана: страница входа в учетные записи Google. Примеры учетных данных вводятся в текстовые поля.

  11. После ввода учетных данных появится запрос на получение разрешений для веб-приложения, которое было только что создано:

    Снимок экрана: страница запроса разрешений для учетных записей Google с запросом на отмену или принятие автономного доступа к веб-приложению.

  12. Нажмите кнопку Принимаю. Теперь вы будете перенаправлены обратно на страницу Регистрация приложения MvcAuth, где можно зарегистрировать учетную запись Google. Вы можете изменить имя локальной регистрации электронной почты, используемое для вашей учетной записи Gmail, но обычно требуется сохранить псевдоним электронной почты по умолчанию (то есть псевдоним, используемый для проверки подлинности). Щелкните Зарегистрировать.

    Снимок экрана, на котором показана страница My A S P dot NET Register Application ( Регистрация приложения). Пример учетной записи Google вводится в текстовое поле электронной почты.

Создание приложения в Facebook и подключение приложения к проекту

Предупреждение

Текущие инструкции по проверке подлинности Facebook OAuth2 см. в разделе Настройка проверки подлинности Facebook.

Изучение данных о членстве с помощью Обозреватель сервера

В меню Вид выберите сервер Обозреватель.

Снимок экрана: раскрывающееся меню Visual Studio VIEW, где выделен Обозреватель сервера.

Разверните узел DefaultConnection (MvcAuth), разверните узел Таблицы, щелкните правой кнопкой мыши AspNetUsers и выберите пункт Показать данные таблицы.

Снимок экрана: параметры меню Обозреватель службы. Развернуты вкладки Подключения к данным, Подключение по умолчанию M v c Auth и Таблицы.

данные таблицы aspnetusers

Добавление данных профиля в класс пользователя

В этом разделе вы добавите дату рождения и родной город в данные пользователя во время регистрации, как показано на следующем рисунке.

reg с родной город и Bday

Откройте файл Models\IdentityModels.cs и добавьте свойства даты рождения и родного города:

public class ApplicationUser : IdentityUser
{
    public string HomeTown { get; set; }
    public System.DateTime? BirthDate { get; set; }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

Откройте файл Models\AccountViewModels.cs и задайте свойства даты рождения и родного города в ExternalLoginConfirmationViewModel.

public class ExternalLoginConfirmationViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    public string HomeTown { get; set; }
    public System.DateTime? BirthDate { get; set; }
}

Откройте файл Controllers\AccountController.cs и добавьте код для даты рождения и родного города в метод действия, ExternalLoginConfirmation как показано ниже:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
    if (User.Identity.IsAuthenticated)
    {
        return RedirectToAction("Manage");
    }

    if (ModelState.IsValid)
    {
        // Get the information about the user from the external login provider
        var info = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return View("ExternalLoginFailure");
        }
        var user = new ApplicationUser() 
        {
            UserName = model.Email, Email = model.Email,
            BirthDate = model.BirthDate,
            HomeTown  = model.HomeTown
        
        };
        IdentityResult result = await UserManager.CreateAsync(user);
        if (result.Succeeded)
        {
            result = await UserManager.AddLoginAsync(user.Id, info.Login);
            if (result.Succeeded)
            {
                await SignInAsync(user, isPersistent: false);
                
                // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // SendEmail(user.Email, callbackUrl, "Confirm your account", "Please confirm your account by clicking this link");
                
                return RedirectToLocal(returnUrl);
            }
        }
        AddErrors(result);
    }

    ViewBag.ReturnUrl = returnUrl;
    return View(model);
}

Добавьте дату рождения и родной город в файл Views\Account\ExternalLoginConfirmation.cshtml :

@model MvcAuth.Models.ExternalLoginConfirmationViewModel
@{
    ViewBag.Title = "Register";
}
<h2>@ViewBag.Title.</h2>
<h3>Associate your @ViewBag.LoginProvider account.</h3>

@using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

    <h4>Association Form</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <p class="text-info">
        You've successfully authenticated with <strong>@ViewBag.LoginProvider</strong>.
            Please enter a user name for this site below and click the Register button to finish
            logging in.
    </p>
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.HomeTown, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.HomeTown, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.HomeTown)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.BirthDate, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.BirthDate, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.BirthDate)
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Удалите базу данных членства, чтобы снова зарегистрировать учетную запись Facebook в приложении и убедиться, что вы можете добавить новую дату рождения и данные профиля родного города.

На Обозреватель решений щелкните значок Показать все файлы, щелкните правой кнопкой мыши Add_Data\aspnet-MvcAuth-dateStamp.mdf<> и выберите команду Удалить.

Снимок экрана: страница Обозреватель решений. Выделены значок Показать все файлы и база данных членства M v c Auth.

В меню Сервис выберите пункт Диспетчер пакетов NuGet, а затем консоль диспетчера пакетов (PMC). Введите следующие команды в PMC.

  1. Enable-Migrations
  2. Инициализация Add-Migration
  3. Update-Database

Запустите приложение и используйте FaceBook и Google для входа и регистрации некоторых пользователей.

Изучение данных членства

В меню Вид выберите сервер Обозреватель.

Снимок экрана: раскрывающееся меню

Щелкните правой кнопкой мыши AspNetUsers и выберите команду Показать данные таблицы.

Снимок экрана: параметры меню Обозреватель сервера. Выделены параметры A s p Net Users (A s p Net Users) и Show Table Data (Показать данные таблицы).

Поля HomeTown и BirthDate показаны ниже.

Снимок экрана: данные таблицы A s p Net Users. В данных таблицы отображаются поля ID, Home Town, Birth Date, Email и Email Confirmed ( Подтверждено).

Выход из приложения и вход с помощью другой учетной записи

Если вы войдете в приложение с помощью Facebook, а затем выйдете из системы и попытаетесь снова войти с другой учетной записью Facebook (используя тот же браузер), вы сразу же войдете в предыдущую учетную запись Facebook, которую вы использовали. Чтобы использовать другую учетную запись, необходимо перейти на Facebook и выйти из нее. Это же правило применяется к любому другому стороннему поставщику проверки подлинности. Кроме того, вы можете войти в систему с другой учетной записью с помощью другого браузера.

Next Steps

Выполните инструкции из моего руководства Создание приложения ASP.NET MVC с проверкой подлинности и базой данных SQL и развертывание в Служба приложений Azure. В этом руководстве показано следующее:

  1. Развертывание приложения в Azure.
  2. Как защитить приложение с помощью ролей.
  3. Как защитить приложение с помощью фильтров RequireHttps и Authorize .
  4. Использование API членства для добавления пользователей и ролей.

Подробное описание работы ASP.NET внешних служб проверки подлинности см. в статье Службы внешней проверки подлинности Роберта Мак-Мюррея. В статье Роберта также подробно рассматривается включение проверки подлинности Microsoft и Twitter. В отличном руководстве По EF/MVC Тома Дайкстры показано, как работать с Entity Framework.