-->

Authentication với ASP.NET Core Identity #1 Tạo cấu trúc project và entities

ASP.NET Core Identity là một built-in của ASP.NET Core, nó cung cấp cho bạn các tính năng đầy đủ và đa dạng về authentication. Ví dụ như: Tạo tài khoản, đăng nhập với user name và password, khóa tài khoản khi đăng nhập quá số lần quy định, xác nhận email,... Hoặc cũng có thể sử dụng những provider bên ngoài giống như: Facebook, Google, Twitter, Microsoft account và nhiều cái khác nữa.  


Và trong series bài viết Authentication với ASP.NET Core Identity này, mình sẽ hướng dẫn các bạn theo từng bước, và rõ ràng nhất.

Tạo cấu trúc project và entities

Bước 1: Tạo solution với kiến trúc như sau:
  • IdentityAuth.WebApp (ASP.NET Core Application)
  • IdentityAuth.Data (Class Library)
Bước 2: Cài đặt các NugetPackage sau: 
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore 
  • Microsoft.Extensions.Configuration.Json 
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.Tools
Bước 3. Trong IdentityAuth.Data tạo folder là Entities.

Bước 4. Trong Entities tạo 2 class AppUser.csAppRole.cs :

public class AppUser : IdentityUser<Guid>
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName { get; set; }
        public DateTimeOffset? DateOfBirth { get; set; }
        public bool? Gender { get; set; }
        public string Comment { get; set; }
        public string Address { get; set; }
        public string UrlAvatar { get; set; }
    }

public class AppRole : IdentityRole<Guid>
    {
        public string Description { get; set; }
    }
Bước 5. Trong IdentityAuth.Data tạo folder là Configurations:

Bước 6. Trong Configurations tạo 2 class AppRoleConfiguration.csAppUserConfiguration.cs:


public class AppUserConfiguration:IEntityTypeConfiguration<AppUser>
    {
        public void Configure (EntityTypeBuilder<AppUser> builder)
        {
            builder.ToTable("AppUsers");
            builder.HasKey(x => x.Id);
            builder.Property(x => x.FirstName).HasMaxLength(50);
            builder.Property(x => x.LastName).HasMaxLength(50);
        }
    }


public class AppRoleConfiguration:IEntityTypeConfiguration<AppRole>
    {
        public void Configure (EntityTypeBuilder<AppRole> builder)
        {
            builder.ToTable("AppRoles");
            builder.HasKey(x => x.Id);
            builder.Property(x => x.Description).HasMaxLength(256);
        }
    }

Bước 7. Trong IdentityAuth.Data tạo folder là Extensions.

Bước 8. Trong Extensions tạo class ModelBuilderExtensions.cs:


public static  class ModelBuilderExtensions
    {
        public static void Seed(this ModelBuilder modelBuilder)
        {

            // Any guid
            var roleId = new Guid("8D04DCE2-969A-435D-BBA4-DF3F325983DC");
            var adminId = new Guid("69BD714F-9576-45BA-B5B7-F00649BE00DE");
            modelBuilder.Entity<AppRole>().HasData(new AppRole
            {
                Id = roleId,
                Name = "Admin",
                NormalizedName = "ADMIN",
                Description = "Administrator role"
            });

            var hasher = new PasswordHasher<AppUser>();

            modelBuilder.Entity<AppUser>().HasData(new AppUser
            {
                Id = adminId,
                UserName = "quochieu@gmail.com",
                NormalizedUserName = "QUOCHIEU@GMAIL.COM",
                Email = "quochieu@gmail.com",
                NormalizedEmail = "QUOCHIEU@GMAIL.COM",
                EmailConfirmed = true,
                PasswordHash = hasher.HashPassword(null, "abc123"),
                SecurityStamp = string.Empty,
                LastName = "Hồ Quốc",
                FirstName = "Hiếu",
                FullName= "Hồ Quốc Hiếu",
                UrlAvatar = "client/assets/img/avt1.jpg"
            });

            modelBuilder.Entity<IdentityUserRole<Guid>>().HasData(new IdentityUserRole<Guid>
            {
                RoleId = roleId,
                UserId = adminId
            });

        }
    }

Bước 9. Trong IdentityAuth.Data tạo folder DataContext.

Bước 10. Trong DataContext tạo 2 class DataDbContext.csDataDbContextFactory.cs:


    public partial class DataDbContext : IdentityDbContext<AppUser, AppRole, Guid>
    {
        public DataDbContext(DbContextOptions options) : base(options)
        {
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            foreach (var foreignKey in modelBuilder.Model.GetEntityTypes()
                .SelectMany(e => e.GetForeignKeys()))
            {
                foreignKey.DeleteBehavior = DeleteBehavior.Restrict;
            }
            //Configure using Fluent API 

            modelBuilder.ApplyConfiguration(new AppUserConfiguration());
            modelBuilder.ApplyConfiguration(new AppRoleConfiguration());



            modelBuilder.Entity<IdentityUserClaim<Guid>>().ToTable("AppUserClaims");
            modelBuilder.Entity<IdentityUserRole<Guid>>().ToTable("AppUserRoles").HasKey(x => new { x.UserId, x.RoleId });
            modelBuilder.Entity<IdentityUserLogin<Guid>>().ToTable("AppUserLogins").HasKey(x => x.UserId);

            modelBuilder.Entity<IdentityRoleClaim<Guid>>().ToTable("AppRoleClaims");
            modelBuilder.Entity<IdentityUserToken<Guid>>().ToTable("AppUserTokens").HasKey(x => x.UserId);

            //Data seeding
            modelBuilder.Seed();
        }
        public DbSet<AppRole> AppRoles { get; set; }
        public DbSet<AppUser> AppUsers { get; set; }

    }
    

        public class DataDbContextFactory : IDesignTimeDbContextFactory<DataDbContext>
    {
        public DataDbContext CreateDbContext(string[] args)
        {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();

            var connectionString = configuration.GetConnectionString("AuthDatabase");

            var optionsBuilder = new DbContextOptionsBuilder<DataDbContext>();
            optionsBuilder.UseSqlServer(connectionString);

            return new DataDbContext(optionsBuilder.Options);
        }
    }
    
Bước 11. Trong IdentityAuth.Data tạo file appsettings.json:

{
  "ConnectionStrings": {
    " AuthDatabase": "Server=CNPM-PC\\SQLEXPRESS;Database=DbAuth;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Bước 12. Rebuild project.

Bước 13. Vào Tools → Nuget Package Manager → Nuget Package Console, chuyển sang như hình dưới:


Bước 14. Sau đó lần lượt gõ các lệnh sau:
  • Add-Migration InitialCreate
  • Update-Database
Bước 15. Kết quả

Lời kết

ASP.NET Core Identity hỗ trợ rất đầy đủ và mạnh mẽ cho việc authentication của ứng dụng. Trong bài viết này, mình chỉ hướng dẫn các bạn tạo cấu trúc project và tạo các entity cần thiết trong các bài sau này. 

Nếu với ứng dụng các bạn không có những yêu cầu quá đặc biệt cho quá trình Authenticate, thì rõ ràng Identity hoàn toàn có thể đáp ứng bài toán của bạn. Ở mức độ cao hơn, các bạn có thể tích hợp đăng nhập cùng Facebook, Google, Twitter,..và tích hợp QR code.

By Hiếu Quốc

Có lẽ bạn thích?

2 comments

  1. Cám ơn Hiếu. Bài viết của Hiếu rất hay và mình đã làm theo.

    Mình gặp lỗi khi chạy lệnh : Add-Migration InitialCreate

    The seed entity for entity type 'AppUser' cannot be added because no value was provided for the required property 'Address'
    The seed entity for entity type 'AppUser' cannot be added because no value was provided for the required property 'Comment'

    Mình đã sửa bằng cách sửa class AppUser để cho phép 2 cột Address và Comment là null

    public string? Comment { get; set; }
    public string? Address { get; set; }

    Cách sửa khác
    là gán dữ liệu cho hàm khởi tạo Seed.

    UrlAvatar = "client/assets/img/avt1.jpg",
    Address="Ha Noi",
    Comment="No Comment"

    ReplyDelete
    Replies
    1. Kết quả đã tạo database thành công

      Delete

Post a Comment