Создание приложения 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 C# слева, Затем — Интернет , а затем — ASP.NET веб-приложение. Присвойте проекту имя MvcAuth и нажмите кнопку ОК.
В диалоговом окне Новый проект ASP.NET щелкните MVC. Если для параметра Проверка подлинности используется не отдельные учетные записи пользователей, нажмите кнопку Изменить проверку подлинности и выберите Учетные записи отдельных пользователей. Установив флажок Узел в облаке, приложение будет очень легко разместить в Azure.
Если вы выбрали Узел в облаке, завершите диалоговое окно настройки.
Использование NuGet для обновления до последней версии ПО промежуточного слоя OWIN
Используйте диспетчер пакетов NuGet для обновления ПО промежуточного слоя OWIN. Выберите Обновления в меню слева. Вы можете нажать кнопку Обновить все или найти только пакеты OWIN (как показано на следующем рисунке):
На рисунке ниже показаны только пакеты OWIN:
В консоли диспетчера пакетов (PMC) можно ввести Update-Package
команду , которая обновит все пакеты.
Нажмите клавишу F5 или CTRL+F5 , чтобы запустить приложение. На рисунке ниже указан номер порта 1234. При запуске приложения вы увидите другой номер порта.
В зависимости от размера окна браузера может потребоваться щелкнуть значок навигации, чтобы просмотреть ссылки Главная, О программе, Контакт, Регистрация и Вход .
Настройка SSL в проекте
Чтобы подключиться к таким поставщикам проверки подлинности, как Google и Facebook, необходимо настроить IIS-Express для использования SSL. Важно продолжать использовать SSL после входа и не возвращаться к HTTP. Файл cookie для входа так же секретный, как ваше имя пользователя и пароль, и без использования SSL вы отправляете его в формате ясного текста по сети. Кроме того, вы уже успели выполнить подтверждение и защитить канал (это основная часть того, что делает HTTPS медленнее, чем HTTP) перед запуском конвейера MVC, поэтому перенаправление обратно на HTTP после входа в систему не ускорит текущий запрос или будущие запросы.
В Обозреватель решений щелкните проект MvcAuth.
Нажмите клавишу F4, чтобы отобразить свойства проекта. Кроме того, в меню Вид можно выбрать Окно свойств.
Измените значение SSL Enabled на True.
Скопируйте URL-адрес SSL (который будет иметь значение
https://localhost:44300/
, если вы не создали другие проекты SSL).В Обозреватель решений щелкните правой кнопкой мыши проект MvcAuth и выберите Свойства.
Выберите вкладку Интернет и вставьте URL-адрес SSL в поле Url-адрес проекта . Сохраните файл (Ctl+S). Этот URL-адрес понадобится для настройки приложений проверки подлинности Facebook и Google.
Добавьте атрибут RequireHttps в контроллер,
Home
чтобы требовать, чтобы все запросы использовали ПРОТОКОЛ HTTPS. Более безопасный подход заключается в добавлении фильтра RequireHttps в приложение. См. раздел "Защита приложения с помощью SSL и атрибута авторизации" в моем руководстве Создание приложения ASP.NET MVC с проверкой подлинности и базой данных SQL и развертывание в Служба приложений Azure. Часть контроллера Home показана ниже.[RequireHttps] public class HomeController : Controller { public ActionResult Index() { return View(); }
Для запуска приложения нажмите сочетание клавиш CTRL+F5. Если вы установили сертификат ранее, можно пропустить оставшуюся часть этого раздела и перейти к разделу Создание приложения Google для OAuth 2 и подключение приложения к проекту. В противном случае следуйте инструкциям, чтобы доверять самозаверяющим сертификату, созданному IIS Express.
Прочтите диалоговое окно Предупреждение системы безопасности и нажмите кнопку Да , если вы хотите установить сертификат, представляющий localhost.
В IE откроется Главная страница без предупреждений SSL.
Google Chrome также принимает сертификат и отображает содержимое HTTPS без предупреждения. Firefox использует собственное хранилище сертификатов, поэтому отображает предупреждение. Для нашего приложения вы можете безопасно щелкнуть Я понимаю риски.
Создание приложения Google для OAuth 2 и подключение приложения к проекту
Предупреждение
Текущие инструкции по Google OAuth см. в разделе Настройка проверки подлинности Google в ASP.NET Core.
Перейдите к Консоли разработчиков Google.
Если вы еще не создали проект, выберите Учетные данные на вкладке слева, а затем щелкните Создать.
На вкладке слева щелкните Учетные данные.
Щелкните Создать учетные данные , а затем идентификатор клиента OAuth.
- В диалоговом окне Создание идентификатора клиента оставьте веб-приложение по умолчанию для типа приложения.
- Задайте для авторизованного источника JavaScript URL-адрес SSL, который вы использовали выше (
https://localhost:44300/
если вы не создали другие проекты SSL). - Задайте для параметра Авторизованный URI перенаправления значение:
https://localhost:44300/signin-google
Щелкните пункт меню OAuth Consent (Согласие OAuth), а затем укажите адрес электронной почты и название продукта. После заполнения формы нажмите кнопку Сохранить.
Щелкните пункт меню Библиотека, найдите API Google+, щелкните его и нажмите кнопку Включить.
На рисунке ниже показаны включенные API.
В диспетчере 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.
Нажмите клавиши CTRL+F5 , чтобы выполнить сборку и запуск приложения. Щелкните ссылку Войти в систему .
В разделе Использовать другую службу для входа щелкнитеGoogle.
Примечание
Если вы пропустите любой из описанных выше шагов, вы получите ошибку HTTP 401. Проверьте описанные выше действия. Если вы пропустили обязательный параметр (например , название продукта), добавьте отсутствующий элемент и сохраните его; Проверка подлинности может занять несколько минут.
Вы будете перенаправлены на сайт Google, где введете свои учетные данные.
После ввода учетных данных появится запрос на получение разрешений для веб-приложения, которое было только что создано:
Нажмите кнопку Принимаю. Теперь вы будете перенаправлены обратно на страницу Регистрация приложения MvcAuth, где можно зарегистрировать учетную запись Google. Вы можете изменить имя локальной регистрации электронной почты, используемое для вашей учетной записи Gmail, но обычно требуется сохранить псевдоним электронной почты по умолчанию (то есть псевдоним, используемый для проверки подлинности). Щелкните Зарегистрировать.
Создание приложения в Facebook и подключение приложения к проекту
Предупреждение
Текущие инструкции по проверке подлинности Facebook OAuth2 см. в разделе Настройка проверки подлинности Facebook.
Изучение данных о членстве с помощью Обозреватель сервера
В меню Вид выберите сервер Обозреватель.
Разверните узел DefaultConnection (MvcAuth), разверните узел Таблицы, щелкните правой кнопкой мыши AspNetUsers и выберите пункт Показать данные таблицы.
Добавление данных профиля в класс пользователя
В этом разделе вы добавите дату рождения и родной город в данные пользователя во время регистрации, как показано на следующем рисунке.
Откройте файл 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<> и выберите команду Удалить.
В меню Сервис выберите пункт Диспетчер пакетов NuGet, а затем консоль диспетчера пакетов (PMC). Введите следующие команды в PMC.
- Enable-Migrations
- Инициализация Add-Migration
- Update-Database
Запустите приложение и используйте FaceBook и Google для входа и регистрации некоторых пользователей.
Изучение данных членства
В меню Вид выберите сервер Обозреватель.
Щелкните правой кнопкой мыши AspNetUsers и выберите команду Показать данные таблицы.
Поля HomeTown
и BirthDate
показаны ниже.
Выход из приложения и вход с помощью другой учетной записи
Если вы войдете в приложение с помощью Facebook, а затем выйдете из системы и попытаетесь снова войти с другой учетной записью Facebook (используя тот же браузер), вы сразу же войдете в предыдущую учетную запись Facebook, которую вы использовали. Чтобы использовать другую учетную запись, необходимо перейти на Facebook и выйти из нее. Это же правило применяется к любому другому стороннему поставщику проверки подлинности. Кроме того, вы можете войти в систему с другой учетной записью с помощью другого браузера.
Next Steps
Выполните инструкции из моего руководства Создание приложения ASP.NET MVC с проверкой подлинности и базой данных SQL и развертывание в Служба приложений Azure. В этом руководстве показано следующее:
- Развертывание приложения в Azure.
- Как защитить приложение с помощью ролей.
- Как защитить приложение с помощью фильтров RequireHttps и Authorize .
- Использование API членства для добавления пользователей и ролей.
Подробное описание работы ASP.NET внешних служб проверки подлинности см. в статье Службы внешней проверки подлинности Роберта Мак-Мюррея. В статье Роберта также подробно рассматривается включение проверки подлинности Microsoft и Twitter. В отличном руководстве По EF/MVC Тома Дайкстры показано, как работать с Entity Framework.