如何在asp.net核心中创建角色并将其分配给用户

我使用asp.net核心默认网站模板和身份validation选择为个人用户帐户。 如何创建角色并将其分配给用户,以便我可以使用控制器中的角色来过滤访问权限。

我在帐户控制器中创建了一个操作,该操作调用一个函数来创建角色并将管理员角色影响到默认用户(您应该删除生产中的默认用户):

private async Task createRolesandUsers() { bool x = await _roleManager.RoleExistsAsync("Admin"); if (!x) { // first we create Admin rool var role = new IdentityRole(); role.Name = "Admin"; await _roleManager.CreateAsync(role); //Here we create a Admin super user who will maintain the website var user = new ApplicationUser(); user.UserName = "default"; user.Email = "default@default.com"; string userPWD = "somepassword"; IdentityResult chkUser = await _userManager.CreateAsync(user, userPWD); //Add default User to Role Admin if (chkUser.Succeeded) { var result1 = await _userManager.AddToRoleAsync(user, "Admin"); } } // creating Creating Manager role x = await _roleManager.RoleExistsAsync("Manager"); if (!x) { var role = new IdentityRole(); role.Name = "Manager"; await _roleManager.CreateAsync(role); } // creating Creating Employee role x = await _roleManager.RoleExistsAsync("Employee"); if (!x) { var role = new IdentityRole(); role.Name = "Employee"; await _roleManager.CreateAsync(role); } } 

之后,您可以创建一个控制器来管理用户的角色。

我的评论被删除了,因为我提供了一个链接,我在这里回答了类似的问题。 Ergo,这次我会更具描述性地回答。 开始。

您可以通过在startup类中创建CreateRoles方法来轻松完成此操作。 这有助于检查角色是否已创建,如果不是,则创建角色; 在应用程序启动。 像这样。

 private async Task CreateRoles(IServiceProvider serviceProvider) { //initializing custom roles var RoleManager = serviceProvider.GetRequiredService>(); var UserManager = serviceProvider.GetRequiredService>(); string[] roleNames = { "Admin", "Manager", "Member" }; 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)); } } //Here you could create a super user who will maintain the web app var poweruser = new ApplicationUser { UserName = Configuration["AppSettings:UserName"], Email = Configuration["AppSettings:UserEmail"], }; //Ensure you have these values in your appsettings.json file string userPWD = Configuration["AppSettings:UserPassword"]; var _user = await UserManager.FindByEmailAsync(Configuration["AppSettings:AdminUserEmail"]); if(_user == null) { var createPowerUser = await UserManager.CreateAsync(poweruser, userPWD); if (createPowerUser.Succeeded) { //here we tie the new user to the role await UserManager.AddToRoleAsync(poweruser, "Admin"); } } } 

然后你可以调用CreateRoles(serviceProvider).Wait(); Startup类中Configure方法的方法。 确保将IServiceProvider作为Configure类中的参数。

在控制器中使用基于角色的授权来过滤用户访问:问题2

你可以这样轻松地做到这一点。

 [Authorize(Roles="Manager")] public class ManageController : Controller { //.... } 

您也可以在动作方法中使用基于角色的授权。 如果愿意,可以分配多个角色

 [Authorize(Roles="Admin, Manager")] public IActionResult Index() { /* ..... */ } 

虽然这样可以正常工作,但为了更好的练习,您可能希望阅读有关使用基于策略的角色检查的信息。 你可以在这里的ASP.NET核心文档中找到它,或者我在这里写的关于它的这篇文章

Temi的答案几乎是正确的,但你不能像他建议的那样从非异步函数中调用异步函数。 你需要做的是在同步函数中进行异步调用,如下所示:

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseIdentity(); // Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); CreateRoles(serviceProvider); } private void CreateRoles(IServiceProvider serviceProvider) { var roleManager = serviceProvider.GetRequiredService>(); var userManager = serviceProvider.GetRequiredService>(); Task roleResult; string email = "someone@somewhere.com"; //Check that there is an Administrator role and create if not Task hasAdminRole = roleManager.RoleExistsAsync("Administrator"); hasAdminRole.Wait(); if (!hasAdminRole.Result) { roleResult = roleManager.CreateAsync(new IdentityRole("Administrator")); roleResult.Wait(); } //Check if the admin user exists and create it if not //Add to the Administrator role Task testUser = userManager.FindByEmailAsync(email); testUser.Wait(); if (testUser.Result == null) { ApplicationUser administrator = new ApplicationUser(); administrator.Email = email; administrator.UserName = email; Task newUser = userManager.CreateAsync(administrator, "_AStrongP@ssword!"); newUser.Wait(); if (newUser.Result.Succeeded) { Task newUserRole = userManager.AddToRoleAsync(administrator, "Administrator"); newUserRole.Wait(); } } } 

关键是使用Task <>类并强制系统以同步方式稍微不同地等待。

以下代码将工作ISA。

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseIdentity(); // Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); CreateRolesAndAdminUser(serviceProvider); } private static void CreateRolesAndAdminUser(IServiceProvider serviceProvider) { const string adminRoleName = "Administrator"; string[] roleNames = { adminRoleName, "Manager", "Member" }; foreach (string roleName in roleNames) { CreateRole(serviceProvider, roleName); } // Get these value from "appsettings.json" file. string adminUserEmail = "someone22@somewhere.com"; string adminPwd = "_AStrongP1@ssword!"; AddUserToRole(serviceProvider, adminUserEmail, adminPwd, adminRoleName); } ///  /// Create a role if not exists. ///  /// Service Provider /// Role Name private static void CreateRole(IServiceProvider serviceProvider, string roleName) { var roleManager = serviceProvider.GetRequiredService>(); Task roleExists = roleManager.RoleExistsAsync(roleName); roleExists.Wait(); if (!roleExists.Result) { Task roleResult = roleManager.CreateAsync(new IdentityRole(roleName)); roleResult.Wait(); } } ///  /// Add user to a role if the user exists, otherwise, create the user and adds him to the role. ///  /// Service Provider /// User Email /// User Password. Used to create the user if not exists. /// Role Name private static void AddUserToRole(IServiceProvider serviceProvider, string userEmail, string userPwd, string roleName) { var userManager = serviceProvider.GetRequiredService>(); Task checkAppUser = userManager.FindByEmailAsync(userEmail); checkAppUser.Wait(); ApplicationUser appUser = checkAppUser.Result; if (checkAppUser.Result == null) { ApplicationUser newAppUser = new ApplicationUser { Email = userEmail, UserName = userEmail }; Task taskCreateAppUser = userManager.CreateAsync(newAppUser, userPwd); taskCreateAppUser.Wait(); if (taskCreateAppUser.Result.Succeeded) { appUser = newAppUser; } } Task newUserRole = userManager.AddToRoleAsync(appUser, roleName); newUserRole.Wait(); } 

我用这个(DI):

 public class IdentitySeed { private readonly ApplicationDbContext _context; private readonly UserManager _userManager; private readonly RoleManager _rolesManager; private readonly ILogger _logger; public IdentitySeed( ApplicationDbContext context, UserManager userManager, RoleManager roleManager, ILoggerFactory loggerFactory) { _context = context; _userManager = userManager; _rolesManager = roleManager; _logger = loggerFactory.CreateLogger(); } public async Task CreateRoles() { if (await _context.Roles.AnyAsync()) {// not waste time _logger.LogInformation("Exists Roles."); return; } var adminRole = "Admin"; var roleNames = new String[] { adminRole, "Manager", "Crew", "Guest", "Designer" }; foreach (var roleName in roleNames) { var role = await _rolesManager.RoleExistsAsync(roleName); if (!role) { var result = await _rolesManager.CreateAsync(new ApplicationRole { Name = roleName }); // _logger.LogInformation("Create {0}: {1}", roleName, result.Succeeded); } } // administrator var user = new ApplicationUser { UserName = "Administrator", Email = "something@something.com", EmailConfirmed = true }; var i = await _userManager.FindByEmailAsync(user.Email); if (i == null) { var adminUser = await _userManager.CreateAsync(user, "Something*"); if (adminUser.Succeeded) { await _userManager.AddToRoleAsync(user, adminRole); // _logger.LogInformation("Create {0}", user.UserName); } } } //! By: Luis Harvey Triana Vega } 

除了Temi Lajumoke的回答之外,值得注意的是,在创建所需角色并将其分配给ASP.NET Core 2.1 MVC Web应用程序中的特定用户之后,启动应用程序后,您可能会遇到方法错误,例如注册或管理帐户:

InvalidOperationException:尝试激活“WebApplication.Areas.Identity.Pages.Account.Manage.IndexModel”时,无法解析类型“Microsoft.AspNetCore.Identity.UI.Services.IEmailSender”的服务。

通过添加AddDefaultUI()方法,可以在ConfigureServices方法中快速纠正类似的错误:

 services.AddIdentity() //services.AddDefaultIdentity() .AddEntityFrameworkStores()    .AddDefaultUI()    .AddDefaultTokenProviders(); 

校验

https://blogs.msdn.microsoft.com/webdev/2018/03/02/aspnetcore-2-1-identity-ui/

和github上的相关主题:

https://github.com/aspnet/Docs/issues/6784了解更多信息。

而为特定用户分配角色可以使用IdentityUser类而不是ApplicationUser。