Open Closed

How to prevent "admin@abp.io" admin user seeding ? #894


User avatar
1
selinkoykiran created

Hello, To prevent inserting abp default admin user we override IdentityDataSeeder and IdentityDataSeedContributor Seed methods. But IdentityDataSeeder method called 2 times in debug mode . At first time method came with admin@abp.io email information and second time our overridden admin definition inserted. But we don't want to add abp default admin user when seeding. What do we need to do ? We made if else for now but we don't want to use like below. Thank you .

  • ABP Framework version: v4.1.2
  • UI type: MVC
  • DB provider: EF Core
  • **Tiered (MVC): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:
Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

4 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi @selinkoykiran

    Can you share your full code?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    alper created
    Support Team Director

    if you send us your customized classes we'll try to reproduce

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    selinkoykiran created

    Hello, In my domain module I add CustomIdentityDataSeeder and CustomIdentityDataSeedContributor classes like below. In the note section we described the situation. Because of dependency injection issues maybe this class hits 2 times . At first time admin email comes with admin@abp.io email second time I could use my custom email . But how does it admin@abp.io default email hit at the first time. How could I prevent it because I think I've already overriden these classes . I don't want to check like if blocks.

    Thank you

    CustomIdentityDataSeedContributor

    using System.Threading.Tasks;
    using Volo.Abp.Data;
    using Volo.Abp.Identity;
    namespace Custom.XXX.Identity
    {
        public class CustomIdentityDataSeedContributor :  IdentityDataSeedContributor
        {
            protected CustomIdentityDataSeeder CustomIdentityDataSeeder { get; }
    
            public CustomIdentityDataSeedContributor(CustomIdentityDataSeeder identityDataSeeder) 
                : base(identityDataSeeder)
            {
                CustomIdentityDataSeeder = identityDataSeeder;
            }
    
            public override Task SeedAsync(DataSeedContext context)
            {
                return CustomIdentityDataSeeder.SeedAsync(
                   "custom@Custom.com",
                   "Pass1234+",
                   context?.TenantId
               );
    
            }
        }
    }
    
    

    CustomIdentityDataSeeder

    using Microsoft.AspNetCore.Identity;
    using Microsoft.Extensions.Options;
    using System;
    using System.Threading.Tasks;
    using Volo.Abp;
    using Volo.Abp.Guids;
    using Volo.Abp.Identity;
    using Volo.Abp.MultiTenancy;
    using Volo.Abp.Uow;
    using IdentityRole = Volo.Abp.Identity.IdentityRole;
    using IdentityUser = Volo.Abp.Identity.IdentityUser;
    
    namespace Custom.XXX.Identity
    {
        public class CustomIdentityDataSeeder : IdentityDataSeeder
        {
            public CustomIdentityDataSeeder(IGuidGenerator guidGenerator,
                IIdentityRoleRepository roleRepository,
                IIdentityUserRepository userRepository,
                ILookupNormalizer lookupNormalizer,
                IdentityUserManager userManager,
                IdentityRoleManager roleManager,
                ICurrentTenant currentTenant,
                IOptions<IdentityOptions> identityOptions)
                : base(guidGenerator, roleRepository, userRepository, lookupNormalizer, userManager, roleManager, currentTenant, identityOptions)
            {
            }
    
            [UnitOfWork]
            public override async Task<IdentityDataSeedResult> SeedAsync(string adminEmail, string adminPassword, Guid? tenantId = null)
            {
                var result = new IdentityDataSeedResult();
                Check.NotNullOrWhiteSpace(adminEmail, nameof(adminEmail));
                Check.NotNullOrWhiteSpace(adminPassword, nameof(adminPassword));
                string adminUserName = "custom";
    		**	//NOTE  we dont want to check like below for abp.io user 
                if (adminEmail == "admin@abp.io")
                {
                    return result;
                }**
                if (tenantId!= Guid.Empty && tenantId != null)
                {
                    adminUserName = "custom2";
                    if(adminEmail == "custom@Custom.com")
                    {
                        adminEmail = "custom2@Custom.com";
                    }
                }
    
                using (CurrentTenant.Change(tenantId))
                {
                    //"admin" user
                   
                    var adminUser = await UserRepository.FindByNormalizedUserNameAsync(
                        LookupNormalizer.NormalizeName(adminUserName)
                    );
    
                    if (adminUser != null)
                    {
                        return result;
                    }
    
                    adminUser = new IdentityUser(
                        GuidGenerator.Create(),
                        adminUserName,
                        adminEmail,
                        tenantId
                    )
                    {
                        Name = adminUserName
                    };
    
                    (await UserManager.CreateAsync(adminUser, adminPassword)).CheckErrors();
                    result.CreatedAdminUser = true;
    
                    //"admin" role
                    const string adminRoleName = "admin";
                    var adminRole = await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName(adminRoleName));
                    if (adminRole == null)
                    {
                        adminRole = new IdentityRole(
                            GuidGenerator.Create(),
                            adminRoleName,
                            tenantId
                        )
                        {
                            IsStatic = true,
                            IsPublic = true
                        };
    
                        (await RoleManager.CreateAsync(adminRole)).CheckErrors();
                        result.CreatedAdminRole = true;
                    }
    
                    (await UserManager.AddToRoleAsync(adminUser, adminRoleName)).CheckErrors();
    
                    return result;
                }
            }
        }
    }
    
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    2
    hikalkan created
    Support Team Software Architect

    This problem occurs since you are registering a second data seed contributor but not removing or replacing the original one.

    Actually, you don't have to replace it just set admin email/password. Open MyProjectNameDbMigrationService in your solution, find the SeedDataAsync method, find this line:

    await _dataSeeder.SeedAsync(tenant?.Id);
    

    Change it like:

    await _dataSeeder.SeedAsync(
    	new DataSeedContext(tenant?.Id)
    		.WithProperty("AdminEmail", "...........")
    		.WithProperty("AdminPassword", "..............")
    	);
    

    I believe we should add this to the startup template, so it will be easy to understand it.

    BTW, if you want to override a service, you should replace it as documented: https://docs.abp.io/en/abp/latest/Dependency-Injection#replace-a-service

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 16, 2026, 14:50
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.