-
Notifications
You must be signed in to change notification settings - Fork 162
Permissions explained
To manage access to features in an ASP.NET Core application uses a concept that AuthP called Permissions. Each Permission defines a flag that can be used to allow access to a feature.
Permissions could be strings (just like ASP.NET Roles are), but I found a C# Enum are better for the following reasons:
- Its easier to find where a specific Permission is used using Visual Studio’s “Find all references”.
- You can provide extra information to an Enum member using attributes. The extra information helps the admin person when looking for a Permission to add to a AuthP’s Role.
- A C# Enum member also has a integer value, which allows a long list of Permissions can be stored more efficiently. This is important as the user's Permissions have to become a claim and need to fit in a Cookie (which has a maximum size of 4048 bytes).
- Using an Enum means IntelliSense can prompt you as to what Enum names you can use. This stops the possibility of typing an incorrect Permission name.
Below is a list of Permissions taken from the Example4 Permissions.
public enum Example4Permissions : ushort
{
NotSet = 0, //error condition
//Here is an example of very detailed control over the selling things
[Display(GroupName = "Sales", Name = "Read", Description = "Can read any sales")]
SalesRead = 20,
[Display(GroupName = "Sales", Name = "Sell", Description = "Can sell items from stock")]
SalesSell = 21,
[Display(GroupName = "Sales", Name = "Return", Description = "Can return an item to stock")]
SalesReturn = 22,
[Display(GroupName = "Employees", Name = "Read", Description = "Can read company employees")]
EmployeeRead = 30,
//other Permissions left out…
//Useful for setting up an SuperAdmin user
//Setting the AutoGenerateFilter to true in the display makes any Role with this enum member
//is hidden from tenant users.
[Display(GroupName = "SuperAdmin", Name = "AccessAll",
Description = "This allows the user to access every feature", AutoGenerateFilter = true)]
AccessAll = ushort.MaxValue,
}
Here are some details about the format of an Enum when working with the AuthP library.
- Each Enum member is given a number rather than letting C# set a number. That's because you don't want to have the value of an Enum change if you add new Enum member before existing Enum members.
- The
Display
attribute to each Enum member provides extra information to help the admin user when creating or changing a AuthP Role. - Enum members with the
AutoGenerateFilter = true
setting inDisplay
attribute are known as advanced Permissions. Advanced Permissions tell AuthP that any Role containing a advanced Permission shouldn't be available to multi-tenant users, i.e. a user linked to a tenant.
NOTE: You will find a more detailed list of rules / characteristics for the Permissions Enums found in Setup Permissions.
The AuthUser overview explains how the ClaimsPrincipal
user in ASP.NET Core gets a claim containing all the permissions that the current user has. There are three ways to use the user's Permission claim to control that user can access.
For a ASP.NET Core MVC or Web API controller you can add the [HasPermission] attribute to an access method in a controller. Here is a example taken from Example2’s WeatherForecastController, which is Web API controller – see the first line.
[HasPermission(PermissionEnum.ReadWeather)]
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
//… other code left out
}
If you are using Blazor, or in any Razor file you can use the HasPermission extension method to check if the current ASP.NET Core’s User has a specific Permission. Here is an example taken from AuthP’s Example1 Razor Pages application.
public class SalesReadModel : PageModel
{
public IActionResult OnGet()
{
if (!User.HasPermission(Example1Permissions.SalesRead))
return Challenge();
return Page();
}
}
The HasPermission
extension method is also useful in any Razor page (e.g. User.HasPermission(Example.SalesRead)
) to decide whether a link/button should be displayed. In Blazor the call would be @context.User.HasPermission(Example.SalesRead)
.
If you are using a front-end library such as React, Angular, Vue and so on, then your front-end needs to know what Permissions the current user has so that the front-end can display the links, buttons etc. that the current user has access to. If you need this you need to set up a WebAPI that will return the current user's permissions.
The IUsersPermissionsService
service has a method called PermissionsFromUser
which returns a list of the Permission names for the current user (or null if no one is logged in or the user is not registered as an AuthUser
). You can see the IUsersPermissionsService
service in action in Example2's AuthenticateController.
- Intro to multi-tenants (ASP.NET video)
- Articles in date order:
- 0. Improved Roles/Permissions
- 1. Setting up the database
- 2. Admin: adding users and tenants
- 3. Versioning your app
- 4. Hierarchical multi-tenant
- 5. Advanced technique with claims
- 6. Sharding multi-tenant setup
- 7. Three ways to add new users
- 8. The design of the sharding data
- 9. Down for maintenance article
- 10: Three ways to refresh claims
- 11. Features of Multilingual service
- 12. Custom databases - Part1
- Videos (old)
- Authentication explained
- Permissions explained
- Roles explained
- AuthUser explained
- Multi tenant explained
- Sharding explained
- How AuthP handles sharding
- How AuthP handles errors
- Languages & cultures explained
- JWT Token refresh explained
- Setup Permissions
- Setup Authentication
- Startup code
- Setup the custom database feature
- JWT Token configuration
- Multi tenant configuration
- Using Permissions
- Using JWT Tokens
- Creating a multi-tenant app
- Supporting multiple languages
- Unit Test your AuthP app