Додавання автентифікації ASP.NET MVC5 до існуючого проекту


164

Я бачив багато подібних сторінок в Інтернеті, але більшість з них використовує новий проект замість існуючого або не має необхідних функцій. Отже, у мене є існуючий MVC 5проект і хочу інтегрувати ASP.NET MVC5 Identity з функціями входу, підтвердженням електронної пошти та перезавантаженням пароля .

На додаток до цього, мені також потрібно створити всі необхідні таблиці в базі даних, тобто користувач, ролі, групи тощо (я використовую EF Code First у своєму проекті). Чи є стаття чи зразок, який відповідає цим потребам? Будь-яка пропозиція буде вдячна. Спасибі заздалегідь...


Який чудовий квестон і який простий солютин подано трохи нижче. Мені подобалось читати це і мені дуже потрібно було інтегруватися в мій існуючий проект.
Ішвор Ханал

Відповіді:


282

Налаштування ідентичності для вашого існуючого проекту не є важкою справою. Ви повинні встановити якийсь пакет NuGet і зробити невелику конфігурацію.

Спочатку встановіть ці пакети NuGet за допомогою консолі Package Manager:

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 this is the 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;
    }
}

Оскільки особа заснована на 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);
            //use the instance that has been created. 
            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;

Ви також можете побачити інші мої відповіді на кшталт цієї та цієї для розширеного використання ідентичності.


2
Обидва рішення виглядають схоже. Я використовував AppRoleі менеджер ролей Identity, щоб класифікувати користувача. А оскільки Roles і RoleManagerвже реалізовані самою Identity, вам не потрібно переписувати вже реалізований код. Я оновлю публікацію, щоб показати вам, як ви можете використовувати ролі. І, як я вже говорив, вам просто потрібно додати AppUserі AppRoleоб'єкти для ініціалізації ідентичності. Спадковуючи свої DbContextз IdentityDbContext<AppUser>усіх необхідних таблиць, додайте свою таблицю. Вам не потрібно нічого робити, лише увімкніть міграцію.
Сем Фараджпур Джамарі

2
Я просто додав деяке використання вибірки. Встановіть Microsoft.AspNet.Identity.EntityFrameworkу свій Домен та інше для інтерфейсу користувача.
Сем Фараджпур Джамарі

2
1) Не хвилюйся за своє web.config. Не замінюйте старого. Прочитайте це для отримання додаткової інформації . Я думаю, що ваш MVC також покращився.
Сем Фараджпур Джамарі

1
2) Ви правильно зробили. 3) без проблем. У вас буде 5 нових столів AspNetRoles AspNetUserClaims AspNetUserLogins AspNetUserRolesіAspNetUsers
Сем Фараджпур Гхамарі

3
Я просто прочитав усі коментарі, які ви залишили, допомагаючи Клінту Іствуду, приємна робота !! Світ потребує більшої кількості людей, як Ви плюсOne
Chef_Code

24

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

  1. Створіть зразок проекту MVC з шаблоном MVC. У цьому коді є весь код, необхідний для реалізації ідентичності - Startup.Auth.cs, IdentityConfig.cs, код контролера облікового запису, Керування контролером, Моделі та пов'язані з ними види.

  2. Встановіть необхідні пакети для власних особи для Identity та OWIN. Ви отримаєте ідею, побачивши посилання у зразку Проекту та відповідь від @Sam

  3. Скопіюйте всі ці коди в існуючий проект. Зауважте, не забудьте додати рядок з'єднання "DefaultConnection" для Identity для відображення у вашій базі даних. Перевірте клас ApplicationDBContext в IdentityModel.cs, де ви знайдете посилання на рядок з'єднання "DefaultConnection".

  4. Це сценарій SQL, який я запустив у своїй наявній базі даних для створення необхідних таблиць:

    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
  5. Перевірте та вирішіть всі помилки, що залишилися, і ви закінчите. Ідентичність впорається з рештою :)


1
Велике спасибі за вашу відповідь та приємні пояснення. Насправді я думаю використовувати інший підхід, але теж спробую. Проголосували +
Джек

2
Я думаю, що це набагато чистіший підхід
niico

3
Окрім класу Startup.Auth.cs, вам потрібно скопіювати Startup.cs, розташований у корені зразкового проекту.
Падміка

Shyamal, чи можете ви додати Startup.cs з коментаря @ Padmika? Це важливо.
Майк

4

Я рекомендую IdentityServer . Це проект .NET Foundation і охоплює багато питань щодо автентифікації та авторизації.

Огляд

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

Для отримання додаткової інформації, наприклад

  • підтримка магазинів користувачів на базі MembershipReboot та ASP.NET Identity
  • підтримка додаткового програмного забезпечення для аутентифікації Katana (наприклад, Google, Twitter, Facebook тощо)
  • підтримка постійності конфігурації на основі EntityFramework
  • підтримка WS-Федерації
  • розширюваність

перевірити документацію та демонстраційну версію .


6
Необхідно враховувати практичне використання IdentityServer, перш ніж сліпо перейти до реалізації IdentityServer.
hanzolo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.