Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use existing login table with asp.net core identity service

I have an existing live application with its own login table which has all the user info stored. Now we have decided to make a mobile app for part of the application. For that we have decided to use asp.net core identity service. What ever articles/blog/videos I have found they all show how to create a new DB and use identity tables. As for us, we cannot use the new identity tables and need to stick with our own login table as it has been used very much throughout the system and application is heavily dependent on it.

So, my question is, is there any way of using ASP.NET core identity with existing database system?

thanks heaps, Maulik

like image 654
user2325928 Avatar asked Oct 17 '22 22:10

user2325928


2 Answers

I do use tables from Identity, however they do not have the same name as the default one. I guess if you customize the fields definitions you could map most of your fields.

Map of an entity property to a column:

b.Property<long>(u => u.Id).HasColumnName("MyIdColumn")

Below you will find extensions that you may use during the init of your builder. Note the "ToTable" method, which is used to override default table names.

    /// <summary>
    /// Init MS.Identity tables + custom AppUser table
    /// </summary>
    public static void InitIdentity(this ModelBuilder builder, string tablesPrefix = "Identity_")
    {
        builder.InitBaseIdentity(tablesPrefix);
        builder.Entity<IdentityUserRole<long>>(b => b.ToTable($"{tablesPrefix}UserRoles"));
        builder.Entity<AppRole>(b => b.ToTable($"{tablesPrefix}Roles"));
        builder.Entity<IdentityRoleClaim<long>>(b => b.ToTable($"{tablesPrefix}RoleClaims"));

    }

    public static void InitBaseIdentity(this ModelBuilder builder, string tablesPrefix = "Identity_")
    {
        builder.Entity<IdentityUserLogin<long>>(b => b.ToTable($"{tablesPrefix}UserLogins"));
        builder.Entity<IdentityUserClaim<long>>(b => b.ToTable($"{tablesPrefix}UserClaims"));
        builder.Entity<AppUser>(b =>
        {
            b.ToTable($"{tablesPrefix}Users");
            b.Property<long>(u => u.Id).ValueGeneratedNever();
            b.Property<int>(u => u.AccessFailedCount);
            b.Property<string>(u => u.ConcurrencyStamp).IsConcurrencyToken();
            b.Property<string>(u => u.Email).HasAnnotation("MaxLength", 256);
            b.Property<bool>(u => u.EmailConfirmed);
            b.Property<bool>(u => u.LockoutEnabled);
            b.Property<DateTimeOffset?>(u => u.LockoutEnd);
            b.Property<string>(u => u.NormalizedEmail).HasAnnotation("MaxLength", 256);
            b.Property<string>(u => u.NormalizedUserName).HasAnnotation("MaxLength", 256);
            b.Property<string>(u => u.PasswordHash);
            b.Property<string>(u => u.PhoneNumber);
            b.Property<bool>(u => u.PhoneNumberConfirmed);
            b.Property<string>(u => u.SecurityStamp);
            b.Property<bool>(u => u.TwoFactorEnabled);
            b.Property<string>(u => u.UserName).HasAnnotation("MaxLength", 256);
            b.HasKey(u => u.Id);
            b.HasIndex(e => e.NormalizedEmail).HasName("EmailIndex");
            b.HasIndex(e => e.NormalizedUserName).HasName("UserNameIndex").IsUnique();
            b.Property(u => u.About).HasMaxLength(255);
            b.Property(u => u.Birthdate);
            b.Property(e => e.CountryCode).IsRequired().HasColumnType("char(2)");
            b.Property(u => u.Country).HasMaxLength(50);
            b.Property(u => u.FirstName).HasMaxLength(50);
            b.Property(u => u.LastName).HasMaxLength(50);
            b.Property(u => u.Gender);

            b.Property(e => e.CreationDate).HasColumnType("datetime").HasDefaultValueSql("getutcdate()");
            b.Property(e => e.LastUpdate).HasColumnType("datetime").HasDefaultValueSql("getutcdate()");
        });
        builder.Entity<IdentityUserToken<long>>(b =>
        {
            b.Property<long>(u => u.UserId);
            b.Property<string>(u => u.LoginProvider);
            b.Property<string>(u => u.Name);
            b.Property<string>(u => u.Value);
            b.HasKey(nameof(IdentityUserToken<long>.UserId), nameof(IdentityUserToken<long>.LoginProvider), nameof(IdentityUserToken<long>.Name));
            b.ToTable($"{tablesPrefix}UserTokens");
        });
    }

However this does not solve the authentication issue, just the mapping of tables. You will also need to customize the way the authentication is done (password check). However I am not sure of which gain you will get with identity as it seems you would have duplicated/uncompatible login strategies. You may have to keep one or the other.

like image 175
Jean Avatar answered Oct 24 '22 06:10

Jean


You can use the database frist way. You have to create your models which will match with the database tables and create your DbContext.

The following page demonstrates an example of how to implement it:

https://learn.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db

like image 20
pitaridis Avatar answered Oct 24 '22 06:10

pitaridis