Search code examples
asp.net-coreasp.net-identityblazor

Restrict account registration to only Admin users with asp.net identity authentication


I am creating a Blazor server app that requires authenticated users in order to prevent external access, and I would like to limit the ability to register new accounts to be only available to Administrator users to prevent unwanted accounts from being created.

I'm using Identity user accounts, scaffolded out for Blazor. Solutions like this at least disable the registration, but from there I need to be able to enable it again for administrative users. I attempted to recreate the register page as a Blazor component, however, using the generated RegisterModel did not seem to work for me.


Solution

  • Upon a large amount of searching - the answer ended up being relatively simple. Muhammad Hammad Maroof's solution although technically correct, confused me and was mostly unhelpful for working with the register page specifically.

    As I am using Role-Based Authentication scaffolded out from Blazor - in a seperate razor page I use this code to set up roles:

    @code {
        protected override async Task OnParametersSetAsync()
        {
            await SetUpAuth();
        }
    
        private async Task SetUpAuth()
        {
            const string Manager = "Manager";
            string[] roles = { Manager };
    
            foreach (var role in roles)
            {
                var roleExist = await roleManager.RoleExistsAsync(role);
    
                if (!roleExist)
                {
                    await roleManager.CreateAsync(new IdentityRole(role));
                }
    
    
            }
    
            var user = await userManager.FindByEmailAsync(config.GetValue<string>("AdminUser"));
    
            if (user != null)
            {
                await userManager.AddToRoleAsync(user, Manager);
            }
        }
    }
    

    Allowing the appropriate user to be marked as an administrator. This page has the [AllowAnonymous] tag on it in order to allow the administrative user as dictated by "AdminUser": "[email protected]", in the appsettings.json page to be able to access the site on initial setup.

    Preventing access to the Blazor site itself from anonymous users was as simple as adding this line to ConfigureServices in the startup class (Code taken from Microsoft Docs)

    services.AddAuthorization(options =>
            {
                options.FallbackPolicy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
    

    From this, allowing access to the register page was significantly easier than I had initially thought (likely due to my lack of .net experience). To do so, all you have to do is locate the Register.cshtml.cs page (I couldn't initially find the controller method Muhammad had mentioned) which I did by using visual studio to right click on the Register Model and then go to definition. This should take you to the Register.cshtml.cs page with the RegisterModel class. In order to restrict access to this page for only a specific role of users, all you have to do is change the [AllowAnonymous] tag above the class to look similar to this:

    [Authorize(Roles ="Manager")]
    public class RegisterModel : PageModel
    

    It's important to note that the same technique used to secure the register page could be used to secure any of the of the other scaffolded Identity pages. For applications where you may have more than a few roles, the method provided by Muhammad of using policy based authorization may be the way to go, and this link he provided is a great tutorial for setting up and using that form of authentication.