I have a blazor server app, and a number of admin pages.
I have my pages in an admin folder, and in that folder I have an _imports.razor file that authorizes a specific AD group:
@attribute [Authorize(Roles = "MyDomain\\MyAppAdministrators")]
That prevents a user from trying to navigate to admin pages.
Anywhere I have links on other pages to admin pages I wrap them in AuthorizeView components:
<AuthorizeView Roles="MyDomain\MyAppAdministrators">
<li class="nav-item">
<NavLink class="nav-link" href="Admin/LaunchCodes">Enter Launch Codes</NavLink>
</li>
</AuthorizeView>
This hides the link if you're not an administrator.
My question is, I want the ad group to be configurable. This is easy to do for the AuthorizeView, but the Authorize attribute is compile time. Is there some way I can set up authorization for pages that I can configure at a folder leve? I'm hoping I don't have to write code on each page because that is vulnerable to developer forgetfulness, or breakage over time as.
I've tried...
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/Admin");
});
But that has no affect, and my understanding is that Blazor isn't compatabile with that approach anyhow.
You do so by moving to Policy Based Authorization. Here's some example code. I've included a custom
IAuthorizationRequirementto show how it's defined and setup.Some constants to define our names
Define the Application Policies and create a dictionary matching polices (defined as strings) and
AuthorizationPolicyobjects.And in
Program:and use:
The Custom Handler set of classes defined in the policies (to demo how to do one):
Checking Authentication
You can check authentication in any component or DI service:
The basics are:
Inject the AuthorizationService. This is how to do it in a component. In a service add it to the CTor.
And then you can authorize like this:
result.Succeededtells you if you were authorized or not.Resourceis just a generic object that you can pass into your customAuthorizationHandlerand cast back.This link will take you to the relevant code in
AuthorizeViewCore- https://github.com/dotnet/aspnetcore/blob/f543e3552514c5c420eeddd55c505bbc131f10a6/src/Components/Authorization/src/AuthorizeViewCore.cs#L99