基于 Blazor 角色的授权 - 类型 'Microsoft.AspNetCore.Identity.RoleManager' 没有服务
Blazor Role based Authorization - No service for type '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
。非常感谢您的帮助。
您的问题在 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>>();
因为你用 :
注册了一个 RoleManager<IdentityRole<Guid>>
和一个 UserManager<ApplicationUser>
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
您需要添加.AddRoles<IdentityRole>()
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
我正在使用 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
。非常感谢您的帮助。
您的问题在 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>>();
因为你用 :
注册了一个RoleManager<IdentityRole<Guid>>
和一个 UserManager<ApplicationUser>
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
您需要添加.AddRoles<IdentityRole>()
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();