Menambahkan ASP.NET MVC5 Identity Authentication ke proyek yang ada

164

Saya telah melihat banyak halaman serupa di web, tetapi kebanyakan dari mereka menggunakan proyek baru, bukan yang sudah ada, atau tidak memiliki fitur yang diperlukan. Jadi, saya memiliki MVC 5proyek yang sudah ada dan ingin mengintegrasikan ASP.NET MVC5 Identity dengan fitur login, konfirmasi email dan pengaturan ulang kata sandi .

Selain itu, saya juga perlu membuat semua tabel yang diperlukan pada basis data yaitu Pengguna, Peran, grup, dll. (Saya menggunakan Kode EF Pertama dalam proyek saya). Apakah ada artikel atau sampel yang sesuai dengan kebutuhan ini? Setiap saran akan dihargai. Terima kasih sebelumnya...

Mendongkrak
sumber
Sungguh sebuah pertanyaan besar dan apa yang diberikan oleh solutin di bawah ini. Saya suka membaca dan sangat perlu untuk mengintegrasikan dalam proyek saya yang ada juga.
Ishwor Khanal

Jawaban:

282

Mengkonfigurasi Identitas ke proyek Anda saat ini bukanlah hal yang sulit. Anda harus menginstal beberapa paket NuGet dan melakukan beberapa konfigurasi kecil.

Pertama instal paket-paket NuGet ini dengan Package Manager Console:

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

Tambahkan kelas pengguna dan dengan IdentityUserwarisan:

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

Lakukan hal yang sama untuk peran:

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

Ubah DbContextorang tua Anda DbContextmenjadi IdentityDbContext<AppUser>seperti ini:

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>
}

Jika Anda menggunakan string koneksi yang sama dan migrasi yang diaktifkan, EF akan membuat tabel yang diperlukan untuk Anda.

Secara opsional, Anda dapat memperluas UserManageruntuk menambahkan konfigurasi dan kustomisasi yang Anda inginkan:

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;
    }
}

Karena Identity didasarkan pada OWIN, Anda perlu mengonfigurasi OWIN juga:

Tambahkan kelas ke App_Startfolder (atau tempat lain jika Anda mau). Kelas ini digunakan oleh OWIN. Ini akan menjadi kelas startup Anda.

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"),
            });
        }
    }
}

Hampir selesai, tambahkan saja baris kode ini ke web.configfile Anda sehingga OWIN dapat menemukan kelas startup Anda.

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

Sekarang di seluruh proyek Anda bisa menggunakan Identity sama seperti proyek baru yang sudah diinstal oleh VS. Pertimbangkan tindakan masuk sebagai contoh

[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);
}

Anda bisa membuat peran dan menambahkan ke pengguna Anda:

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

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

Anda juga bisa menambahkan peran ke pengguna, seperti ini:

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

Dengan menggunakan AuthorizeAnda dapat menjaga tindakan atau pengendali Anda:

[Authorize]
public ActionResult MySecretAction() {}

atau

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

Anda juga dapat menginstal paket tambahan dan mengkonfigurasinya untuk memenuhi kebutuhan Anda seperti Microsoft.Owin.Security.Facebookatau yang Anda inginkan.

Catatan: Jangan lupa untuk menambahkan spasi nama yang relevan ke file Anda:

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;

Anda juga dapat melihat jawaban saya yang lain seperti ini dan ini untuk penggunaan Identitas tingkat lanjut.

Sam Farajpour Ghamari
sumber
2
Kedua solusi terlihat serupa. Saya telah menggunakan AppRoledan role manager Identity untuk mengklasifikasikan pengguna. Dan sejak Roles dan RoleManagersudah diterapkan oleh Identity sendiri Anda tidak perlu menulis ulang kode yang sudah diterapkan. Saya akan memperbarui pos untuk menunjukkan kepada Anda bagaimana Anda dapat menggunakan peran. Dan seperti yang saya katakan sebelumnya, Anda hanya perlu menambahkan AppUserdan AppRoleentitas untuk menginisialisasi Identity. Dengan mewarisi Anda DbContextdari IdentityDbContext<AppUser>semua tabel yang diperlukan tambahkan tabel Anda. Anda tidak perlu melakukan apa pun cukup aktifkan migrasi.
Sam Farajpour Ghamari
2
Saya baru saja menambahkan beberapa penggunaan sampel. Instal Microsoft.AspNet.Identity.EntityFrameworkke Domain Anda dan lainnya untuk UI.
Sam Farajpour Ghamari
2
1) Jangan khawatir tentang Anda web.config. Jangan ganti yang lama. Baca ini untuk info lebih lanjut . Saya pikir MVC Anda juga ditingkatkan.
Sam Farajpour Ghamari
1
2) Anda melakukannya dengan benar. 3) tidak masalah. Anda akan memiliki 5 meja baru AspNetRoles AspNetUserClaims AspNetUserLogins AspNetUserRolesdanAspNetUsers
Sam Farajpour Ghamari
3
Saya baru saja membaca semua komentar yang Anda tinggalkan membantu Clint Eastwood, Nice Job !! Dunia membutuhkan lebih banyak orang seperti Anda plusOne
Chef_Code
24

Inilah yang saya lakukan untuk mengintegrasikan Identity dengan database yang ada.

  1. Buat proyek MVC sampel dengan template MVC. Ini memiliki semua kode yang diperlukan untuk implementasi Identitas - Startup.Auth.cs, IdentityConfig.cs, kode Pengontrol Akun, Kelola Pengontrol, Model dan tampilan terkait.

  2. Instal paket nuget yang diperlukan untuk Identity dan OWIN. Anda akan mendapatkan ide dengan melihat referensi di Proyek sampel dan jawabannya oleh @Sam

  3. Salin semua kode ini ke proyek Anda yang ada. Harap dicatat jangan lupa untuk menambahkan string koneksi "DefaultConnection" untuk Identity untuk dipetakan ke database Anda. Silakan periksa kelas ApplicationDBContext di IdentityModel.cs di mana Anda akan menemukan referensi ke string koneksi "DefaultConnection".

  4. Ini adalah skrip SQL yang saya jalankan pada basis data yang ada untuk membuat tabel yang diperlukan:

    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. Periksa dan selesaikan kesalahan yang tersisa dan Anda selesai. Identitas akan menangani sisanya :)

Shyamal Parikh
sumber
1
Terima kasih banyak atas balasan Anda dan penjelasan yang bagus. Sebenarnya saya berpikir untuk menggunakan pendekatan lain, tetapi saya juga akan mencobanya. Memilih +
Jack
2
Saya pikir ini adalah pendekatan yang jauh lebih bersih
niico
3
Selain kelas Startup.Auth.cs Anda perlu menyalin Startup.cs yang terletak di root proyek sampel.
Padmika
Shyamal dapatkah Anda menambahkan Startup.cs dari komentar @ Padmika? Ini penting.
Mike
4

Saya merekomendasikan IdentityServer . Ini adalah proyek .NET Foundation dan mencakup banyak masalah tentang otentikasi dan otorisasi.

Gambaran

IdentityServer adalah kerangka kerja .NET / Katana dan komponen yang dapat di-host yang memungkinkan penerapan sistem akses tunggal dan akses untuk aplikasi web modern dan API menggunakan protokol seperti OpenID Connect dan OAuth2. Ini mendukung berbagai klien seperti ponsel, web, SPA dan aplikasi desktop dan dapat diperpanjang untuk memungkinkan integrasi dalam arsitektur baru dan yang sudah ada.

Untuk informasi lebih lanjut, mis

  • dukungan untuk toko pengguna berbasis MembershipReboot dan ASP.NET Identity
  • dukungan untuk middleware otentikasi Katana tambahan (mis. Google, Twitter, Facebook dll)
  • dukungan untuk kegigihan konfigurasi EntityFramework
  • dukungan untuk WS-Federation
  • kemungkinan diperpanjang

lihat dokumentasi dan demo .

TotPeRo
sumber
6
Penggunaan praktis dari IdentityServer harus dipertimbangkan sebelum secara membabi buta melompat ke implementasi IdentityServer.
hanzolo