I'm new to blazor server. I have implemented asp.net core identity role-based authorization. But I don't want to hardcode roles on the Authorize attribute. I want to create roles later and specify in which controller and action it has access without touching source code.
As you can see in the image above how can I create dynamic role based authorization in blazor server
CodePudding user response:
You need to implement and Authorize via a policy.
You can create a permission that can be assigned to any Role
. In combination with a Policy
that checks for the permission.
This allows you to create roles at runtime and assign permissions to these new roles. When a user is then assigned a role the policy will see the permissions attached to the role.
Your screen would become groupings of 6 permissions that would be assigned to each role. Which would require 6 Policies.
I would consider using a class like the following:
Permission.cs
public sealed class Permission
{
public static readonly IReadOnlyList<Permission> Permissions = new List<Permission>
{ RolesView, RolesCreate, RolesUpdate, RolesDelete, UserRoleView, UserRoleUpdate };
public static explicit operator string(Permission p) => p.Key;
public static Permission RolesView => new Permission
{
Key = "Permission.Roles.View",
Display = "Role List",
GroupName = "Role Management"
};
public static Permission RolesCreate => new Permission
{
Key = "Permission.Roles.Create",
Display = "Create Role",
GroupName = "Role Management"
};
public static Permission RolesUpdate => new Permission
{
Key = "Permission.Roles.Update",
Display = "Edit Role",
GroupName = "Role Management"
};
public static Permission RolesDelete => new Permission
{
Key = "Permission.Roles.Delete",
Display = "Delete",
GroupName = "Role Management"
};
public static Permission UserRoleView => new Permission
{
Key = "Permission.UserRole.View",
Display = "User List",
GroupName = "User Role Management"
};
public static Permission UserRoleUpdate => new Permission
{
Key = "Permission.UserRole.Update",
Display = "Edit User Roles",
GroupName = "User Role Management"
};
public string Key { get; private set; }
public string Display { get; private set; }
public string GroupName { get; private set; }
}
services.AddAuthorization(options =>
{
...
options.AddPolicy(name: "UserRoleView", policy =>
policy.RequireClaim(Permission.UserRoleView));
...
});
[Authorize(Policy = "UserRoleView")]
Use the RoleManager
s methods AddClaimAsync
& RemoveClaimAsync
using the Permission
as the claim exploiting the explicit string conversion.
CodePudding user response:
As an add on to Brian's answer, there's a PolicyBuilder
factory that you can use to build out your policies. Here's a simple example from one of my applications:
public static class AppPolicies
{
public const string IsAdmin = "IsAdmin";
public const string IsUser = "IsUser";
public const string IsVisitor = "IsVisitor";
public static AuthorizationPolicy IsAdminPolicy
=> new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireRole("Admin")
.Build();
public static AuthorizationPolicy IsUserPolicy
=> new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireRole("Admin", "User")
.Build();
public static AuthorizationPolicy IsVisitorPolicy
=> new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireRole("Admin", "User", "Visitor")
.Build();
public static Dictionary<string, AuthorizationPolicy> Policies
{
get
{
var policies = new Dictionary<string, AuthorizationPolicy>();
policies.Add(IsAdmin, IsAdminPolicy);
policies.Add(IsUser, IsUserPolicy);
policies.Add(IsVisitor, IsVisitorPolicy);
return policies;
}
}
}
And use it like this:
services.AddAuthorization(config =>
{
foreach (var policy in AppPolicies.Policies)
{
config.AddPolicy(policy.Key, policy.Value);
}
});