ASP.Net core 7, IsInRoleAsync returns false

89 views Asked by At

I try to have admin user generated in the database when the starts. I add a user and a role to the db using the IdentityDbContext. here is the context:

public class UserContext : IdentityDbContext<PetShopUser>
{
   
    public UserContext(DbContextOptions<UserContext> options): base(options){}

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.Entity<PetShopUser>().HasData(
            new PetShopUser()
            {
                Id = "1",
                UserName = "Admin",
                NormalizedUserName = "ADMIN",
                PasswordHash =new PasswordHasher<PetShopUser>().HashPassword(null!, "He!!oWorld1")
               
            }
            );
        
        builder.Entity<IdentityRole>().HasData(new IdentityRole() { Id="1" ,Name = "Admin" });

        builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>() {RoleId = "1", UserId = "1"});
    }

}

program.cs is also configured for using Identity and Roles:

builder.Services.AddDbContext<UserContext>(options => options.UseLazyLoadingProxies().UseSqlServer(userConnectionsString));
builder.Services.AddIdentity<PetShopUser, IdentityRole>().AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<UserContext>();

and when logging in, I go to the action in the controller:

[HttpPost]
public async Task<IActionResult> Login(PetShopUser user, string password)
{
    var result = await _signInManager.PasswordSignInAsync(user, password, false, false);
    var user1 = await _userManager.FindByNameAsync(user.UserName!);
    
    var isAdmin = await _userManager.IsInRoleAsync(user, "Admin");
    if (result.Succeeded)
    {
        return RedirectToAction("Index", "Home", new { isLoggedIn = true });
    }
    else
        return RedirectToAction("Index", "Home", new { isLoggedIn = true });
}

I am relatively new to asp net core and new to identities and roles in general... I searched for a solution and did not found anything, I must be missing something but cant really tell what it is.

Resources for learning identities and roles in an ordered way will be welcomed and solution for the problem as well..

Best regards.

1

There are 1 answers

0
Md Farid Uddin Kiron On

I try to have admin user generated in the database when the starts. I add a user and a role to the db using the IdentityDbContext

I have tried to simulate your scenario. Not sure what you have in your AspNetRoles and AspNetUserRoles table as you haven't shared details and your seed class also doesn't containing roles and user roles mappings.

Moreover, for asp.net identity you should check correct PetShopUser, IdentityRole and IdentityUserRole mappings in database in order to work everything as expected.

As per my simulation test, it seems IdentityRole and IdentityUserRole mapping seed class causing the issue. You would also need to seed IdentityRole and IdentityUserRole.

In addition, after migration double check database table value if those have created as per seed class defination.

Let's have a look in practice:

Model:

namespace DotnetIdentityApp.Models
{
    public class PetShopUser : IdentityUser
    {
    }
    public class ApplicationRole : IdentityRole
    {
    }
    public class ApplicationUserRole : IdentityUserRole<Guid>
    {
    }
}

DbContext:

public class ApplicationDbContext : IdentityDbContext<PetShopUser, IdentityRole, string>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            string UserId = "101";
            string RoleId = "1";

           
           
            //Creating New Pet User
            var appUser = new PetShopUser
            {
                Id = UserId,
                Email = "[email protected]",
                UserName = "admin",
                NormalizedUserName = "admin"
                
            };

            //Setting user password
            PasswordHasher<PetShopUser> ph = new PasswordHasher<PetShopUser>();
            appUser.PasswordHash = ph.HashPassword(appUser, "mytestpassword");

            //Seeding Pet User
            builder.Entity<PetShopUser>().HasData(appUser);

            //Seeding admin role
            builder.Entity<IdentityRole>().HasData(new IdentityRole
            {
                Name = "Admin",
                NormalizedName = "Admin",
                Id = RoleId,
                ConcurrencyStamp = RoleId
            });


            //Mapping User and Role
            builder.Entity<IdentityUserRole<string>>().HasData(new IdentityUserRole<string>
            {
                RoleId = RoleId,
                UserId = UserId
            });
        }

    }

Note: I have renamed UserContext to ApplicationDbContext. After executing migration command, please check if the database have following table value:

AspNetUsers:

enter image description here

AspNetRoles:

enter image description here

AspNetUserRoles:

enter image description here

Program.cs:

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));


builder.Services.AddDefaultIdentity<PetShopUser>(options => options.SignIn.RequireConfirmedAccount = false)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

Note: As per your scenario, please rename ApplicationDbContext to UserContext

Output:

enter image description here

enter image description here

Note: I would strongly recommend you to check our official document here for further details.