Razor Pages adding and assigning roles

Question:

I am trying to figure out how in Razor Pages 2.1. add roles and assign them to users. I need to create an administrator role and assign it to a pre-created (seed) user.

I found how to do this in MVC is done in MVC (second article) , but unfortunately, this approach in Razor Pages did not work for me.

Show me how you can create and assign roles in Razor Pages 2.1.

Answer:

It turned out to be done as follows. First, I used the code suggested by user Paul Madson at https://stackoverflow.com/questions/42471866/how-to-create-roles-in-asp-net-core-and-assign-them-to-users . I pasted the following method into the Startup.cs file. It creates an administrator role and assigns it to a pre-created user.

    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
            {
            Email = email,
            UserName = email,
            Name = email
            };

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

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

    }

Then, in the same file, in the Configure method, I added the IServiceProvider serviceProvider argument, that is, in terms of the signature, it began to look like Configure (…, IServiceProvider serviceProvider). In it, at the very end, I added the CreateRoles (serviceProvider) line. For this code to work, you must first create it, for example, in the Data folder. next class:

using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Sobopedia.Data
{
    public class ApplicationUser: IdentityUser
    {
        public string Name { get; set; }
    }
}

Finally, in the ConfigureServices method, replace

services.AddIdentity<ApplicationUser>()
            .AddEntityFrameworkStores<SobopediaContext>()
            .AddDefaultTokenProviders();

on

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

As a result, after starting the program, you will have a new role in the AspNetRoles table, and a new user with this role in the AspNetUsers table.

Unfortunately, if you created a template with initial authorization, then when adding

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

the Login and Registration pages will stop working. To fix this, you need to:

  1. Scaffold Identity following ( https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-2.1&tabs=visual-studio ). If you are using a template with pre-created authorization, see Scaffold identity into a Razor project with authorization.

  2. After creating the template, replace all IdentityUser with ApplicationUser throughout the solution . Except for the ApplicationUser class, which must still inherit from IdentityUser.

  3. Remove everything related to EmailSernder from Areas / identity / Pages / Account / Register.cs (that is, the model) if you do not have its implementation.

To check the correctness of this solution, you can do the following. At the end of the ConfigureServices method in the Startup.cs class, add the following:

services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator"));
            });

    services.AddMvc().AddRazorPagesOptions(options =>
                {
options.Conventions.AuthorizePage("/Contact","RequireAdministratorRole");
                }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Also, for safety reasons or if this code doesn't work, you can add [Authorize (Roles = "Administrator")] to the Contact page model so that it looks like this:

namespace Sobopedia.Pages
{
    [Authorize(Roles = "Administrator")]
    public class ContactModel : PageModel
    {
        public string Message { get; set; }

        public void OnGet()
        {
            Message = "Your contact page.";
        }
    }
}

Now, you can get to the Contact page only if you log in with the login someone@somewhere.com and the password _AStrongP @ ssword! 123. The method may fail if, when creating an administrator, a password containing prohibited and not containing required characters is used.

Scroll to Top