Добавление аутентификации идентификатора ASP.NET MVC5 в существующий проект

Я видел много похожих страниц в Интернете, но большинство из них используют новый проект вместо существующего или не имеют необходимых функций. Итак, у меня есть существующий проект MVC 5 и вы хотите интегрировать идентификатор ASP.NET MVC5 с регистрацией, подтверждением электронной почты и паролем reset.

В дополнение к этому мне также необходимо создать все необходимые таблицы в базе данных, то есть пользователя, ролей, групп и т.д. (я использую EF Code First в своем проекте). Есть ли статья или образец, соответствующий этим потребностям? Любое предложение будет оценено по достоинству. Спасибо заранее...

Ответ 1

Настройка Identity для вашего существующего проекта - это не сложно. Вы должны установить пакет NuGet и выполнить небольшую конфигурацию.

Сначала установите эти пакеты NuGet в консоли диспетчера пакетов:

PM> Install-Package Microsoft.AspNet.Identity.Owin 
PM> Install-Package Microsoft.AspNet.Identity.EntityFramework
PM> Install-Package Microsoft.Owin.Host.SystemWeb 

Добавьте класс пользователя и с наследованием IdentityUser:

public class AppUser : IdentityUser
{
    //add your custom properties which have not included in IdentityUser before
    public string MyExtraProperty { get; set; }  
}

Сделайте то же самое для роли:

public class AppRole : IdentityRole
{
    public AppRole() : base() { }
    public AppRole(string name) : base(name) { }
    // extra properties here 
}

Измените родительскую форму DbContext DbContext на IdentityDbContext<AppUser> следующим образом:

public class MyDbContext : IdentityDbContext<AppUser>
{
    // Other part of codes still same 
    // You don't need to add AppUser and AppRole 
    // since automatically added by inheriting form IdentityDbContext<AppUser>
}

Если вы используете ту же строку подключения и активировали миграцию EF, создайте для вас необходимые таблицы.

Дополнительно вы можете расширить UserManager, чтобы добавить желаемую конфигурацию и настройку:

public class AppUserManager : UserManager<AppUser>
{
    public AppUserManager(IUserStore<AppUser> store)
        : base(store)
    {
    }

    // this method is called by Owin therefore best place to configure your User Manager
    public static AppUserManager Create(
        IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {
        var manager = new AppUserManager(
            new UserStore<AppUser>(context.Get<MyDbContext>()));

        // optionally configure your manager
        // ...

        return manager;
    }
}

Так как Identity основана на OWIN, вам также нужно настроить OWIN:

Добавьте класс в папку App_Start (или где-нибудь еще, если хотите). Этот класс используется OWIN

namespace MyAppNamespace
{
    public class IdentityConfig
    {
        public void Configuration(IAppBuilder app)
        {
            app.CreatePerOwinContext(() => new MyDbContext());
            app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
            app.CreatePerOwinContext<RoleManager<AppRole>>((options, context) =>
                new RoleManager<AppRole>(
                    new RoleStore<AppRole>(context.Get<MyDbContext>())));

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Home/Login"),
            });
        }
    }
}

Почти просто добавьте эту строку кода в ваш файл web.config, чтобы OWIN мог найти ваш класс запуска.

<appSettings>
    <!-- other setting here -->
    <add key="owin:AppStartup" value="MyAppNamespace.IdentityConfig" />
</appSettings>

Теперь во всем проекте вы можете использовать Identity, как и новый проект, уже установленный VS. Рассмотрим действие входа в систему, например

[HttpPost]
public ActionResult Login(LoginViewModel login)
{
    if (ModelState.IsValid)
    {
        var userManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
        var authManager = HttpContext.GetOwinContext().Authentication;

        AppUser user = userManager.Find(login.UserName, login.Password);
        if (user != null)
        {
            var ident = userManager.CreateIdentity(user, 
                DefaultAuthenticationTypes.ApplicationCookie);
            AuthManager.SignIn(
                new AuthenticationProperties { IsPersistent = false }, ident);
            return Redirect(login.ReturnUrl ?? Url.Action("Index", "Home"));
        }
    }
    ModelState.AddModelError("", "Invalid username or password");
    return View(login);
}

Вы можете создавать роли и добавлять к своим пользователям:

public ActionResult CreateRole(string roleName)
{
    var roleManager=HttpContext.GetOwinContext().GetUserManager<RoleManager<AppRole>>();

    if (!roleManager.RoleExists(roleName))
        roleManager.Create(new AppRole(roleName));
    // rest of code
} 

Вы можете добавить любую роль к любому пользователю, как это:

UserManager.AddToRole(UserManager.FindByName("username").Id, "roleName");

Используя Authorize, вы можете защитить свои действия или контроллеры:

[Authorize]
public ActionResult MySecretAction() {}

или

[Authorize(Roles = "Admin")]]
public ActionResult MySecretAction() {}

Также вы можете установить дополнительный пакет и настроить их для соответствия вашим требованиям, например Microsoft.Owin.Security.Facebook или в зависимости от того, что вы хотите.

Примечание. Не забудьте добавить соответствующие импространства в ваши файлы:

using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;

Вы также можете увидеть мои другие ответы, например и для расширенного использования Identity.

Ответ 2

Это то, что я сделал для интеграции Identity с существующей базой данных.

  • Создайте образец MVC-проекта с шаблоном MVC. У этого есть весь код, необходимый для реализации Identity - Startup.Auth.cs, IdentityConfig.cs, Код Контроля Пользователя, Управление Контроллером, Модели и связанные с ним виды.

  • Установите необходимые пакеты nuget для Identity и OWIN. Вы получите представление, увидев ссылки в образце Project и ответ @Sam

  • Скопируйте весь этот код в существующий проект. Обратите внимание, что не забудьте добавить строку подключения "DefaultConnection" для Identity для сопоставления с вашей базой данных. Проверьте класс ApplicationDBContext в IdentityModel.cs, где вы найдете ссылку на строку подключения "DefaultConnection".

  • Это SQL script Я запускал свою существующую базу данных для создания необходимых таблиц:

    USE ["YourDatabse"]
    GO
    /****** Object:  Table [dbo].[AspNetRoles]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetRoles](
    [Id] [nvarchar](128) NOT NULL,
    [Name] [nvarchar](256) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetRoles] PRIMARY KEY CLUSTERED 
    (
      [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUserClaims]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUserClaims](
       [Id] [int] IDENTITY(1,1) NOT NULL,
       [UserId] [nvarchar](128) NOT NULL,
       [ClaimType] [nvarchar](max) NULL,
       [ClaimValue] [nvarchar](max) NULL,
    CONSTRAINT [PK_dbo.AspNetUserClaims] PRIMARY KEY CLUSTERED 
    (
       [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUserLogins]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUserLogins](
        [LoginProvider] [nvarchar](128) NOT NULL,
        [ProviderKey] [nvarchar](128) NOT NULL,
        [UserId] [nvarchar](128) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUserLogins] PRIMARY KEY CLUSTERED 
    (
        [LoginProvider] ASC,
        [ProviderKey] ASC,
        [UserId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUserRoles]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUserRoles](
       [UserId] [nvarchar](128) NOT NULL,
       [RoleId] [nvarchar](128) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUserRoles] PRIMARY KEY CLUSTERED 
    (
        [UserId] ASC,
        [RoleId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO
    /****** Object:  Table [dbo].[AspNetUsers]    Script Date: 16-Aug-15 6:52:25 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[AspNetUsers](
        [Id] [nvarchar](128) NOT NULL,
        [Email] [nvarchar](256) NULL,
        [EmailConfirmed] [bit] NOT NULL,
        [PasswordHash] [nvarchar](max) NULL,
        [SecurityStamp] [nvarchar](max) NULL,
        [PhoneNumber] [nvarchar](max) NULL,
        [PhoneNumberConfirmed] [bit] NOT NULL,
        [TwoFactorEnabled] [bit] NOT NULL,
        [LockoutEndDateUtc] [datetime] NULL,
        [LockoutEnabled] [bit] NOT NULL,
        [AccessFailedCount] [int] NOT NULL,
        [UserName] [nvarchar](256) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
     GO
     ALTER TABLE [dbo].[AspNetUserClaims]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
     REFERENCES [dbo].[AspNetUsers] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserClaims] CHECK CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId]
     GO
     ALTER TABLE [dbo].[AspNetUserLogins]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
     REFERENCES [dbo].[AspNetUsers] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserLogins] CHECK CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId]
     GO
     ALTER TABLE [dbo].[AspNetUserRoles]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId] FOREIGN KEY([RoleId])
     REFERENCES [dbo].[AspNetRoles] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId]
     GO
     ALTER TABLE [dbo].[AspNetUserRoles]  WITH CHECK ADD  CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
     REFERENCES [dbo].[AspNetUsers] ([Id])
     ON DELETE CASCADE
     GO
     ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId]
     GO
    
  • Проверьте и устраните все оставшиеся ошибки, и все готово. Идентичность будет обрабатывать остальные:)

Ответ 3

Я рекомендую IdentityServer. Это .NET Foundation и охватывает многие проблемы аутентификации и авторизации.

Обзор

IdentityServer - это основанная на .NET/Katana инфраструктура и хост-компонент, который позволяет реализовать единый вход и контроль доступа для современных веб-приложений и API-интерфейсов, используя протоколы, такие как OpenID Connect и OAuth2. Он поддерживает широкий спектр клиентов, таких как мобильные, веб-сайты, SPA и настольные приложения, а также расширяется для интеграции в новые и существующие архитектуры.

Для получения дополнительной информации, например

  • поддержка пользовательских магазинов MembershipReboot и ASP.NET
  • поддержка дополнительного промежуточного ПО аутентификации Katana (например, Google, Twitter, Facebook и т.д.)
  • поддержка постоянной конфигурации на основе EntityFramework
  • поддержка WS-Federation
  • расширяемость

просмотрите documentation и samples.