В этой главе мы установим и настроим инфраструктуру Identity, что займет немного времени. Если вы зайдете в Visual Studio и создадите новое приложение ASP.NET Core и выберете полный шаблон веб-приложения с аутентификацией, настроенной для отдельных учетных записей пользователей, этот новый проект будет включать все биты инфраструктуры Identity, настроенной для вас.
Мы начали с пустого проекта. Теперь мы настроим платформу Identity с нуля, что является хорошим способом узнать обо всех компонентах полного шаблона приложения, потому что это может сбить с толку, если вы не проработали подробно все коды.
Для начала нам нужно установить зависимость Microsoft.AspNet.Identity . Мы продолжим, установив Microsoft.AspNet.Identity.EntityFramework и затем внедрив платформу Identity, которая работает с Entity Framework.
-
Если мы возьмем зависимость от Identity.EntityFramework, пакет будет включать пакет Identity.
-
Если вы создаете свои собственные хранилища данных, вы можете работать только с пакетом Identity.
-
После того, как наши зависимости установлены, мы можем создать пользовательский класс User со всей информацией, которую мы хотим сохранить о пользователе.
-
Для этого приложения мы собираемся наследовать от класса, предоставляемого платформой Identity, и этот класс предоставит нам все необходимое, например, свойство Username и место для хранения хешированных паролей.
Если мы возьмем зависимость от Identity.EntityFramework, пакет будет включать пакет Identity.
Если вы создаете свои собственные хранилища данных, вы можете работать только с пакетом Identity.
После того, как наши зависимости установлены, мы можем создать пользовательский класс User со всей информацией, которую мы хотим сохранить о пользователе.
Для этого приложения мы собираемся наследовать от класса, предоставляемого платформой Identity, и этот класс предоставит нам все необходимое, например, свойство Username и место для хранения хешированных паролей.
-
Нам также потребуется изменить наш класс FirstAppDemoDbContext, чтобы он наследовал от класса IdentityDb инфраструктуры Identity .
-
IdentityDb дает нам все, что нам нужно хранить как пользовательскую информацию в Entity Framework. После того, как у нас есть класс User и DBContext , нам нужно будет настроить службы Identity в приложении с помощью метода ConfigureServices класса Startup.
-
Точно так же, как когда нам нужно было добавить сервисы для поддержки инфраструктуры MVC, каркасу Identity нужны сервисы, добавленные в приложение для работы.
-
Эти службы включают в себя такие службы, как служба UserStore и SignInManager .
-
Мы будем внедрять эти сервисы в наш контроллер для создания пользователей и выдачи файлов cookie в соответствующее время.
-
Наконец, во время запуска метода Configure нам потребуется добавить промежуточное программное обеспечение Identity.
-
Это промежуточное программное обеспечение не только поможет превратить файлы cookie в личность пользователя, но также гарантирует, что пользователь не увидит пустую страницу с ответом 401.
Нам также потребуется изменить наш класс FirstAppDemoDbContext, чтобы он наследовал от класса IdentityDb инфраструктуры Identity .
IdentityDb дает нам все, что нам нужно хранить как пользовательскую информацию в Entity Framework. После того, как у нас есть класс User и DBContext , нам нужно будет настроить службы Identity в приложении с помощью метода ConfigureServices класса Startup.
Точно так же, как когда нам нужно было добавить сервисы для поддержки инфраструктуры MVC, каркасу Identity нужны сервисы, добавленные в приложение для работы.
Эти службы включают в себя такие службы, как служба UserStore и SignInManager .
Мы будем внедрять эти сервисы в наш контроллер для создания пользователей и выдачи файлов cookie в соответствующее время.
Наконец, во время запуска метода Configure нам потребуется добавить промежуточное программное обеспечение Identity.
Это промежуточное программное обеспечение не только поможет превратить файлы cookie в личность пользователя, но также гарантирует, что пользователь не увидит пустую страницу с ответом 401.
Давайте теперь следуем инструкциям ниже.
Шаг 1 — Нам нужно продолжить, добавив зависимость от платформы Identity. Давайте добавим зависимость Microsoft.AspNet.Identity.EntityFramework в файл project.json. Это будет включать в себя все другие необходимые пакеты удостоверений, которые нам нужны.
{ "version": "1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final" }, "commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" }, "frameworks": { "dnx451": { }, "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
Шаг 2 — Сохраните этот файл. Visual Studio восстанавливает пакеты, и теперь мы можем добавить наш класс User. Давайте добавим класс User, щелкнув правой кнопкой мыши на папке Models и выбрав Add → Class.
Назовите этого пользователя класса и нажмите кнопку Добавить, как на скриншоте выше. В этом классе вы можете добавить свойства для хранения любой информации о пользователе, которую вы хотите сохранить.
Шаг 3 — Давайте выведем класс User из класса, предоставленного платформой Identity. Это класс IdentityUser, который находится в пространстве имен Identity.EntityFramework.
using Microsoft.AspNet.Identity.EntityFramework; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Models { public class User : IdentityUser { } }
Шаг 4 — Теперь давайте перейдем к IdentityUser, поместим курсор на этот символ и нажмите F12, чтобы увидеть представление метаданных Visual Studio.
#region Assembly Microsoft.AspNet.Identity.EntityFramework, Version = 3.0.0.0, namespace Microsoft.AspNet.Identity.EntityFramework { public class IdentityUser : IdentityUser<string> { public IdentityUser(); public IdentityUser(string userName); } }
Шаг 5. Вы можете видеть, что IdentityUser является производным от IdentityUser строки. Вы можете изменить тип первичного ключа, унаследовав его от IdentityUser и указав наш параметр универсального типа. Вы также можете хранить вещи с первичным ключом, который в идеале является целочисленным значением.
Шаг 6 — Давайте теперь поместим курсор на IdentityUser строки и снова нажмите F12, чтобы перейти к представлению метаданных.
Теперь вы можете видеть всю информацию, связанную с пользователем по умолчанию. Информация включает в себя следующее —
-
Поля, которые мы не будем использовать в этом приложении, но доступны для использования.
-
Платформа Identity может отслеживать количество неудачных попыток входа в систему для конкретного пользователя и может блокировать эту учетную запись в течение определенного периода времени.
-
Поля для хранения PasswordHash, PhoneNumber. Мы будем использовать два важных поля — PasswordHash и UserName.
-
Мы также будем неявно использовать первичный ключ и свойство ID пользователя. Вы также можете использовать это свойство, если вам нужно выполнить запрос для конкретного пользователя.
Поля, которые мы не будем использовать в этом приложении, но доступны для использования.
Платформа Identity может отслеживать количество неудачных попыток входа в систему для конкретного пользователя и может блокировать эту учетную запись в течение определенного периода времени.
Поля для хранения PasswordHash, PhoneNumber. Мы будем использовать два важных поля — PasswordHash и UserName.
Мы также будем неявно использовать первичный ключ и свойство ID пользователя. Вы также можете использовать это свойство, если вам нужно выполнить запрос для конкретного пользователя.
Шаг 7 — Теперь нам нужно убедиться, что пользователь включен в наш DBContext. Итак, давайте откроем FirstAppDemoDBContext, который есть в нашем приложении, и вместо того, чтобы выводить его напрямую из DBContext, который является встроенным базовым классом Entity Framework, нам теперь нужно извлечь его из IdentityDbContext.
using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Data.Entity; namespace FirstAppDemo.Models { public class FirstAppDemoDbContext : IdentityDbContext<User> { public DbSet<Employee> Employees { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = FirstAppDemo;Integrated Security = True; Connect Timeout = 30;Encrypt = False;TrustServerCertificate = True; ApplicationIntent = ReadWrite;MultiSubnetFailover = False"); } } }
Шаг 8 — Класс IdentityDbContext также находится в пространстве имен Microsoft.AspNet.Identity.EntityFramework, и мы можем указать тип пользователя, который он должен хранить. Таким образом, любые дополнительные поля, которые мы добавляем в класс User, попадают в базу данных.
-
IdentityDbContext предоставляет дополнительные наборы данных DbSets не только для хранения пользователя, но и для информации о пользовательских ролях и заявках пользователей.
-
Наш пользовательский класс готов сейчас. Наш класс FirstAppDemoDbContext настроен для работы со структурой Identity.
-
Теперь мы можем перейти к Configure и ConfigureServices, чтобы настроить Identity Framework.
IdentityDbContext предоставляет дополнительные наборы данных DbSets не только для хранения пользователя, но и для информации о пользовательских ролях и заявках пользователей.
Наш пользовательский класс готов сейчас. Наш класс FirstAppDemoDbContext настроен для работы со структурой Identity.
Теперь мы можем перейти к Configure и ConfigureServices, чтобы настроить Identity Framework.
Шаг 9 — Давайте начнем с ConfigureServices . В дополнение к нашим службам MVC и службам Entity Framework нам необходимо добавить наши службы идентификации. Это добавит все сервисы, на которые опирается платформа Identity для выполнения своей работы.
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext> (option => option.UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); }
-
Метод AddIdentity принимает два параметра общего типа — тип объекта пользователя и тип объекта роли.
-
Два параметра универсального типа — это типы нашего пользователя — класс User, который мы только что создали, и класс Role, с которым мы хотим работать. Теперь мы будем использовать встроенную IdentityRole. Этот класс находится в пространстве имен EntityFramework.
-
Когда мы используем Entity Framework с Identity, нам также необходимо вызвать второй метод — AddEntityFrameworkStores.
-
Метод AddEntityFrameworkStores настроит такие службы, как UserStore, служба, используемая для создания пользователей и проверки их паролей.
Метод AddIdentity принимает два параметра общего типа — тип объекта пользователя и тип объекта роли.
Два параметра универсального типа — это типы нашего пользователя — класс User, который мы только что создали, и класс Role, с которым мы хотим работать. Теперь мы будем использовать встроенную IdentityRole. Этот класс находится в пространстве имен EntityFramework.
Когда мы используем Entity Framework с Identity, нам также необходимо вызвать второй метод — AddEntityFrameworkStores.
Метод AddEntityFrameworkStores настроит такие службы, как UserStore, служба, используемая для создания пользователей и проверки их паролей.
Шаг 10. Следующие две строки — все, что нам нужно для настройки служб для приложения.
services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>();
Шаг 11 — Нам также нужно добавить промежуточное программное обеспечение. Расположение того, куда мы вставляем промежуточное ПО, важно, потому что, если мы вставим промежуточное ПО слишком поздно в конвейер, у него никогда не будет возможности обработать запрос.
И если нам требуются проверки авторизации внутри наших контроллеров MVC, нам нужно вставить промежуточное ПО Identity перед платформой MVC, чтобы убедиться, что файлы cookie, а также ошибки 401 успешно обрабатываются.
public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseIdentity(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
Шаг 12. В то место, куда мы вставляем промежуточное ПО, мы добавляем промежуточное ПО Identity. Ниже приведена полная реализация файла Startup.cs.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using FirstAppDemo.Services; using Microsoft.AspNet.Routing; using System; using FirstAppDemo.Entities; using Microsoft.Data.Entity; using FirstAppDemo.Models; using Microsoft.AspNet.Identity.EntityFramework; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID = 398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext>(option => option.UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseIdentity(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Шаг 13 — Давайте теперь двигаться вперед, создав приложение. В следующей главе нам нужно добавить еще одну миграцию Entity Framework, чтобы убедиться, что у нас есть схема Identity в нашей базе данных SQL Server.