首页 > 解决方案 > Blazor 基于角色的授权 - 没有“Microsoft.AspNetCore.Identity.RoleManager”类型的服务

问题描述

我正在使用来自GitHub的免费项目,该项目使用 Blazor 和 EF Identity 和 SQLite。它是我学习和添加更多功能的一个很好的起点。目前,我想为项目添加授权,以允许特定用户访问特定页面。我的第一步是添加默认角色和帐户。我设法找到了一些在启动期间执行此操作的示例代码。但是,我收到以下运行时错误。

在此处输入图像描述

我通过互联网搜索示例代码和修复。不幸的是,无论我用我对 ASP.NET 的有限知识做什么,它都不起作用。这是我的启动代码。我已将CreateRoles功能添加到项目中,其余不变。

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
              options.UseSqlite("Filename=data.db"));

            services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit = false;
                options.Password.RequiredLength = 6;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireLowercase = false;
                //options.Password.RequiredUniqueChars = 6;

                // Lockout settings
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 10;
                options.Lockout.AllowedForNewUsers = true;

                // User settings
                options.User.RequireUniqueEmail = false;
            });

            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });

            services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.HttpOnly = false;
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = 401;
                    return Task.CompletedTask;
                };
            });

            services.AddControllers().AddNewtonsoftJson();
            services.AddResponseCompression(opts =>
            {
                opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                    new[] { "application/octet-stream" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider service)
        {
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetService<ApplicationDbContext>().Database.Migrate();
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapFallbackToFile("index.html");
            });

            CreateRoles(service).GetAwaiter().GetResult();
        }

        private async Task CreateRoles(IServiceProvider serviceProvider)
        {
            //initializing custom users and roles   
            var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
            string[] roleNames = { "Admin", "User", "HR" };
            IdentityResult roleResult;

            foreach (var roleName in roleNames)
            {
                var roleExist = await RoleManager.RoleExistsAsync(roleName);
                if (!roleExist)
                {
                    //create the roles and seed them to the database: Question 1  
                    roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
                }
            }

            IdentityUser user = await UserManager.FindByEmailAsync("admin@gmail.com");

            if (user == null)
            {
                user = new IdentityUser()
                {
                    UserName = "admin",
                    Email = "admin@gmail.com",
                };
                await UserManager.CreateAsync(user, "Passwd@12");
            }

            bool role = await UserManager.IsInRoleAsync(user, "Admin");
            if (!role)
            {
                await UserManager.AddToRoleAsync(user, "Admin");
            }

        }
    }

该项目可以在 GitHub 上的BlazorWithIdentity找到。我希望能够创建角色以便我可以AuthorizeView在这个项目中使用。非常感谢您的帮助。

标签: c#asp.netentity-frameworkasp.net-identityblazor

解决方案


您的问题存在于CreateRoles

//initializing custom users and roles   
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();

用。。。来代替 :

//initializing custom users and roles   
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole<Guid>>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

因为您注册了 aRoleManager<IdentityRole<Guid>>和 a UserManager<ApplicationUser>

services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()

推荐阅读