简体   繁体   English

如何创建“角色管理器”<IdentityRole> “在 ASP.Net Core 中?

[英]How to create "RoleManager<IdentityRole>" in ASP.Net Core?

I am unable to use RoleManager in my application.我无法在我的应用程序中使用 RoleManager。 I am trying to seed an Admin user in to a .NET Core web application, and I want this user to have a role called "canEdit".我正在尝试将 Admin 用户植入 .NET Core Web 应用程序,并且我希望该用户拥有一个名为“canEdit”的角色。 What I've got currently produces this error:我目前所得到的会产生此错误:

System.InvalidOperationException: 'No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]' has been registered.' System.InvalidOperationException:'没有为类型'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]'注册的服务。'

I have tried various ways of doing this.我尝试了各种方法来做到这一点。 I have tried using Service Provider to do it, dependency injection, etc. but they all give the same error.我曾尝试使用服务提供者来执行此操作、依赖注入等,但它们都给出了相同的错误。

ServiceProvider in the Configure method of Startup.cs: Startup.cs 的 Configure 方法中的 ServiceProvider:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();

var scopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
var scope = scopeFactory.CreateScope();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
DbInitializer dbi = new DbInitializer(roleManager);
dbi.Initialize(context, userManager);

DBInitializer Class: DBInitializer 类:

Constructor:构造函数:

private readonly RoleManager<IdentityRole> rm;

    public DbInitializer(RoleManager<IdentityRole> rm)
    {
        this.rm = rm;
    }

CreateAdmin method: CreateAdmin 方法:

private async Task CreateAdmin(UserManager<ApplicationUser> userManager, ApplicationDbContext context)
    {
        IdentityResult ir;
        ir = await rm.CreateAsync(new IdentityRole("canEdit"));
        IdentityRole canEdit = new IdentityRole("canEdit");
        ApplicationUser admin = new ApplicationUser
        {
            UserName = "Member1@email.com"
        };
        if (context.Users.Where(u => u.UserName == admin.UserName).Count() == 0)
        {
            userManager.CreateAsync(admin, "Password123!").Wait();
            userManager.AddToRoleAsync(admin, "canEdit").Wait();
        }
    }

CreateUsers method:创建用户方法:

private void CreateUsers(UserManager<ApplicationUser> userManager, ApplicationDbContext context)
    {

        CreateAdmin(userManager, context).Wait();

        ApplicationUser customer1 = new ApplicationUser
        {
            UserName = "Customer1@email.com"
        };
        if (context.Users.Where(u => u.UserName == customer1.UserName).Count() > 0)
        {
            userManager.CreateAsync(customer1, "Password123!").Wait();
        }

This repeats for customer2, 3, 4, 5. I can optimise this by removing the need to create an object which I may not need (in the case where the email exists), but I was trying to knock up this method and the CreateAdmin method quickly, then optimise later.这对客户 2、3、4、5 重复。我可以通过消除创建我可能不需要的对象的需要来优化它(在电子邮件存在的情况下),但我试图敲开这个方法和 CreateAdmin快速方法,然后再优化。 Unfortunately I then ran in to an error which I have been unable to fix.不幸的是,我遇到了一个我无法修复的错误。

The end goal is for the DbInitializer class to seed 5 regular users, and 1 admin user with extra permissions/claims.最终目标是让 DbInitializer 类播种 5 个普通用户和 1 个具有额外权限/声明的管理员用户。

Do you have the Identity services registered? 您是否注册了身份服务? Also, I ran into issues when I used .Wait() instead of await. 另外,当我使用.Wait()而不是等待时,我也遇到了问题。

  services.AddIdentity<ApplicationUser,IdentityRole>(options=>
        {
            options.User.RequireUniqueEmail = true;               
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;      

        })
            .AddDefaultTokenProviders()
            .AddDefaultUI()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddAuthorization();
        services.AddAuthentication();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 

If this helps, here is how I seeded my Db. 如果有帮助,这是我播种Db的方式。

  public SeedDataBase(IServiceProvider _serviceProvider, ApplicationDbContext _context)
    {
        serviceProvider = _serviceProvider;
        context = _context;

    }
    private IServiceProvider serviceProvider;
    private ApplicationDbContext context;
    private ApplicationUser superUser;

    public async Task Seed()
    {

        await CreateSuperUser();
        await SeedDb();
    }
    private async Task CreateSuperUser()
    {
        var _userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        var userExists = await _userManager.GetUsersInRoleAsync("FULLADMIN");

        if (userExists.Count() < 1)
        {
            var _roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var _signinManger = serviceProvider.GetRequiredService<SignInManager<ApplicationUser>>();

            superUser = new ApplicationUser()
            {
                UserName = "superuser@superuser.com",
                Email = "superuser@superuser.com",
                FirstName = "Super",
                LastName = "User",
                AccountCreationDate = DateTime.Now.ToShortDateString(),
                Access = ApplicationUser.Permissions.FullAdmin
            };
            var permissions = Enum.GetNames(typeof(ApplicationUser.Permissions));

            foreach (var s in permissions)
            {
                await _roleManager.CreateAsync(new IdentityRole(s));
            }
            await _userManager.CreateAsync(superUser, "SecureP@ssword1234");
            await _userManager.AddToRoleAsync(superUser, Enum.GetName(typeof(ApplicationUser.Permissions), superUser.Access));
        }
    }

that may help someone in the future , you have to use the await for the RoleManager.CreateAsync method这可能会在将来对某人有所帮助,您必须对 RoleManager.CreateAsync 方法使用 await

then to verify if the operation was compeleted successfully use然后验证操作是否成功完成使用

var res = await _roleManager.CreateAsync(new IdentityRole(Role));
  if(res.Succeeded)
  {
    return Ok("created successfully !");
  }    


               `

If you use IdentityServer4 or Duende.IdentityServer in .NET 5 < with Individual user accounts then edit Startup.cs .如果您在 .NET 5 < 中使用 IdentityServer4 或 Duende.IdentityServer 以及个人用户帐户,则编辑Startup.cs Look for the following values:查找以下值:

services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();

Edit it to look like this:编辑它看起来像这样:

services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM