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

时间:2017-02-26 17:37:23

标签: c# asp.net asp.net-mvc asp.net-core asp.net-identity-3

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

8 个答案:

答案 0 :(得分:56)

我的评论已删除,因为我提供了一个指向我回答here的类似问题的链接。 Ergo,这次我会更具描述性地回答。到此为止。

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

private async Task CreateRoles(IServiceProvider serviceProvider)
{
    //initializing custom roles 
    var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
    var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
    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");
        }
    }
}

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

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

您可以轻松完成此操作。

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

您也可以在动作方法中使用基于角色的授权。如果您将

分配多个角色
[Authorize(Roles="Admin, Manager")]
public IActionResult Index()
{
   //....
}

虽然这种方法很好,但为了更好的练习,您可能希望阅读有关使用基于策略的角色检查的信息。您可以在ASP.NET核心文档here上找到它,或者我写的关于它的文章here

答案 1 :(得分:35)

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

Properties

创建控制器以管理用户的角色之后。

答案 2 :(得分:18)

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<RoleManager<IdentityRole>>();
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
        Task<IdentityResult> roleResult;
        string email = "someone@somewhere.com";

        //Check that there is an Administrator role and create if not
        Task<bool> 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<ApplicationUser> testUser = userManager.FindByEmailAsync(email);
        testUser.Wait();

        if (testUser.Result == null)
        {
            ApplicationUser administrator = new ApplicationUser();
            administrator.Email = email;
            administrator.UserName = email;

            Task<IdentityResult> newUser = userManager.CreateAsync(administrator, "_AStrongP@ssword!");
            newUser.Wait();

            if (newUser.Result.Succeeded)
            {
                Task<IdentityResult> newUserRole = userManager.AddToRoleAsync(administrator, "Administrator");
                newUserRole.Wait();
            }
        }

    }

关键是使用任务&lt;&gt;类和强制系统以同步方式稍微不同的方式等待。

答案 3 :(得分:6)

我用这个(DI):

public class IdentitySeed
{
    private readonly ApplicationDbContext _context;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<ApplicationRole> _rolesManager;
    private readonly ILogger _logger;

    public IdentitySeed(
        ApplicationDbContext context,
        UserManager<ApplicationUser> userManager,
        RoleManager<ApplicationRole> roleManager,
         ILoggerFactory loggerFactory) {
        _context = context;
        _userManager = userManager;
        _rolesManager = roleManager;
        _logger = loggerFactory.CreateLogger<IdentitySeed>();
    }

    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
}

答案 4 :(得分:3)

在配置方法中声明您的角色管理器(启动)

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, RoleManager<IdentityRole> roleManager)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

        Task.Run(()=>this.CreateRoles(roleManager)).Wait();
    }


    private async Task CreateRoles(RoleManager<IdentityRole> roleManager)
    {
        foreach (string rol in this.Configuration.GetSection("Roles").Get<List<string>>())
        {
            if (!await roleManager.RoleExistsAsync(rol))
            {
                await roleManager.CreateAsync(new IdentityRole(rol));
            }
        }
    }

可选 - 在 appsettings.JSON 中(这取决于您想从何处获取角色)

{
"Roles": [
"SuperAdmin",
"Admin",
"Employee",
"Customer"
  ]
}

答案 5 :(得分:2)

以下代码适用于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);
    }

    /// <summary>
    /// Create a role if not exists.
    /// </summary>
    /// <param name="serviceProvider">Service Provider</param>
    /// <param name="roleName">Role Name</param>
    private static void CreateRole(IServiceProvider serviceProvider, string roleName)
    {
        var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();

        Task<bool> roleExists = roleManager.RoleExistsAsync(roleName);
        roleExists.Wait();

        if (!roleExists.Result)
        {
            Task<IdentityResult> roleResult = roleManager.CreateAsync(new IdentityRole(roleName));
            roleResult.Wait();
        }
    }

    /// <summary>
    /// Add user to a role if the user exists, otherwise, create the user and adds him to the role.
    /// </summary>
    /// <param name="serviceProvider">Service Provider</param>
    /// <param name="userEmail">User Email</param>
    /// <param name="userPwd">User Password. Used to create the user if not exists.</param>
    /// <param name="roleName">Role Name</param>
    private static void AddUserToRole(IServiceProvider serviceProvider, string userEmail, 
        string userPwd, string roleName)
    {
        var userManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

        Task<ApplicationUser> checkAppUser = userManager.FindByEmailAsync(userEmail);
        checkAppUser.Wait();

        ApplicationUser appUser = checkAppUser.Result;

        if (checkAppUser.Result == null)
        {
            ApplicationUser newAppUser = new ApplicationUser
            {
                Email = userEmail,
                UserName = userEmail
            };

            Task<IdentityResult> taskCreateAppUser = userManager.CreateAsync(newAppUser, userPwd);
            taskCreateAppUser.Wait();

            if (taskCreateAppUser.Result.Succeeded)
            {
                appUser = newAppUser;
            }
        }

        Task<IdentityResult> newUserRole = userManager.AddToRoleAsync(appUser, roleName);
        newUserRole.Wait();
    }

答案 6 :(得分:2)

2020年更新。如果您愿意,这是另一种方式。

 IdentityResult res = new IdentityResult();
 var _role = new IdentityRole();
 _role.Name = role.RoleName;
  res = await _roleManager.CreateAsync(_role);
  if (!res.Succeeded)
  {
        foreach (IdentityError er in res.Errors)
        {
             ModelState.AddModelError(string.Empty, er.Description);
         }
         ViewBag.UserMessage = "Error Adding Role";
         return View();
  }
  else
  {
        ViewBag.UserMessage = "Role Added";
        return View();
   }

答案 7 :(得分:1)

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

  

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

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

services.AddIdentity<IdentityUser, IdentityRole>()
//services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .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。