Search code examples
c#blazor-server-side.net-7.0

Blazor Server - Authorization to access page


I have a Blazor Server application I'm playing with to learn some more. I'm at the point of trying to work out Authorization.

My App has integration with AzureAD and SSO. Once I sign into the browser session I can then get the user information and populate their Menu. I have a restricted the menu to only show items based on user permission, this is loaded via a database query and EF.

What I'm trying to understand is how do I use the AuthorizeView ect to check the current page agains the users "allowed" menu items to see if they are supposed to be there?

i.e. Prevent the user from copying the page /admin and pasting the URL into their browser. I've been doing some reading but it's not making much sense as a lot of it is focues on "roles". I get the "AuthorizeView" and "Authorized" components but unsure how to overwrite this to see if the current page is "valid" for the user.

I'm using Blazor Server, .NET7.0.


Solution

  • One way you can approach this is by using policy definitions and then tagging pages with an attribute authorizing it to those policies. You can also use the Policy attribute in the AuthorizeView component in say, navigation links, to hide the navigation option itself.

    I'm going to give a very basic example of what this would look like by defining a policy based on an AAD extension attribute, but the approach using a role manager tied to a database isn't much different, conceptually - I'll post a link after this example that has an example.

    The following example is looking at an extension attribute named isVegetarian defined in AAD. It is meant to convey the idea of using the policy-based approach at a high level, but specific implementations for a more complex set of roles is better described in the link provided below.

    In your Program.cs Main method, where you're adding services, you might have something that looks like this:

    builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy("isVegetarian", policy => policy.RequireClaim("extension_isVegetarian", new[] { "true" }));
        // By default, all incoming requests will be authorized according to the default policy
        options.FallbackPolicy = options.DefaultPolicy;
    });
    

    The page access is controlled by adding an attribute to your page like so:

    @attribute [Authorize(Policy = "isVegetarian")]
    

    Or in your navmenu.razor, using the Policy attribute in the AuthorizeView component to wrap the menu option:

    <AuthorizeView Policy="isVegetarian">
        //link to vegetarian options
    </AuthorizeView>
    

    You can modify the conditions of the policy requirements of course. Specifically you may want the policy to require role membership and/or other characteristics (RequireRole, RequireUserName, RequireAssertion, etc.).

    The following link has a more built out description of using policy based authorization in Blazor: https://shauncurtis.github.io/Articles/Policy-Based-Authorization.html