Sang.AspNetCore.RoleBasedAuthorization 1.2.7

dotnet add package Sang.AspNetCore.RoleBasedAuthorization --version 1.2.7
                    
NuGet\Install-Package Sang.AspNetCore.RoleBasedAuthorization -Version 1.2.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sang.AspNetCore.RoleBasedAuthorization" Version="1.2.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sang.AspNetCore.RoleBasedAuthorization" Version="1.2.7" />
                    
Directory.Packages.props
<PackageReference Include="Sang.AspNetCore.RoleBasedAuthorization" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sang.AspNetCore.RoleBasedAuthorization --version 1.2.7
                    
#r "nuget: Sang.AspNetCore.RoleBasedAuthorization, 1.2.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Sang.AspNetCore.RoleBasedAuthorization@1.2.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Sang.AspNetCore.RoleBasedAuthorization&version=1.2.7
                    
Install as a Cake Addin
#tool nuget:?package=Sang.AspNetCore.RoleBasedAuthorization&version=1.2.7
                    
Install as a Cake Tool

Sang.AspNetCore.RoleBasedAuthorization

NuGet version (Sang.AspNetCore.RoleBasedAuthorization)

Role-Based Authorization for ASP.NET.

For the Chinese version, see README.zh-CN.md.

Instructions

Step 1

Add this package:

Install-Package Sang.AspNetCore.RoleBasedAuthorization
Step 2

Add RBAC services:

builder.Services.AddSangRoleBasedAuthorization();

You can also configure the administrator role name. The default is SangRBAC_Administrator:

builder.Services.AddSangRoleBasedAuthorization(options =>
{
    options.AdministratorRoleName = "Admin";
});
Step 3

Add the ResourceAttribute tag to the Controller or action that needs to be authorized:

[Route("api/[controller]")]
[ApiController]
[ResourceModule("roles", "Role permissions")]
public class RolesController : ControllerBase
{
    [Resource("delete", "Delete role", "Allows deleting non-system roles")]
    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        return Ok();
    }
}

The resource and action keys are stable English identifiers and form the roles.delete permission code. Display names and descriptions stay next to the endpoint, making authorization intent self-documenting.

Use the complete form for an operation outside a controller's module:

[Resource("weather", "read", "Weather", "View weather", "Allows viewing weather forecasts")]
Step 4

After completing the above operations, the authorization check will verify whether User.Claims contains the corresponding Permission. The claims can be included directly in the JWT token, or the middleware described in the next section can load them by role or user identity before authorization. When using the middleware, the JWT does not need to contain Permission claims.

var claims = new List<Claim>
{
    new Claim(ClaimTypes.NameIdentifier, "uid"),
    new Claim(ClaimTypes.Name, "UserName"),
    new Claim(ClaimTypes.Email, "test@exp.com"),
    new Claim(ClaimTypes.Role, "user"),
};
var token = new JwtSecurityToken(
        "Issuer",
        "Audience",
        claims,
        expires: DateTime.UtcNow.AddSeconds(3600),
        signingCredentials: credentials
    );

Note: If the role is named SangRBAC_Administrator, no authorization check will be done. This role name can be customized via SangRoleBasedAuthorizationOptions.AdministratorRoleName.

Optional Features

Use the provided role-permission middleware. You can also use this component alone.

Step 1

Implement IRolePermission to get permissions by role and, optionally, permissions directly assigned to the current user:

public class MyRolePermission : IRolePermission
{
    public Task<List<Claim>> GetRolePermissionClaimsByName(string roleName)
    {
        List<Claim> list = new();
        // your code
        return Task.FromResult(list);
    }

    public Task<List<Claim>> GetUserPermissionClaims(ClaimsPrincipal user)
    {
        var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        // Query permissions directly assigned to userId.
        return Task.FromResult(new List<Claim>());
    }
}

GetUserPermissionClaims has a default empty implementation, so existing role-only implementations do not need to change. Role and direct-user permissions are merged, deduplicated by Claim Type and Value, and added to the current request's User once.

Then add the service:

builder.Services.AddRolePermission<MyRolePermission>();
Step 2

Enable this middleware before app.UseAuthorization(); and after app.UseAuthentication();:

app.UseAuthentication();
app.UseRolePermission();
app.UseAuthorization();
Options

UseRolePermission accepts the following options:

1. option.Always

Whether to always check and execute the addition. By default, the middleware only adds permissions when the current request has a ResourceAttribute to be verified.

Wildcard Permission Matching

The authorization handler supports the following permission claim formats:

  • "roles" — grants all actions under the resource.
  • "roles.delete" — grants a specific action.
  • "roles.*" — grants all actions under the resource (explicit wildcard).
  • "*" — grants all resources and actions (global super-administrator permission).

Resource Details

Use ResourceData.GetResourceInfos() to retrieve hierarchical metadata for permissions actually used by the application:

var permissions = ResourceData.GetResourceInfos();

The result groups actions under their resource:

[
    {
        "resourceKey": "values",
        "resourceName": "Values",
        "actions": [
            {
                "actionKey": "read",
                "actionName": "View values",
                "description": "Allows viewing value lists",
                "permission": "values.read"
            }
        ]
    }
]

Frontend Localization

ResourceName, ActionName, and Description are default display text. Frontends can use ResourceKey and Permission as translation keys, then fall back to the backend text when a translation is absent. This avoids additional name-key fields.

{
    "zh-CN": {
        "values": { "name": "数值" },
        "values.read": { "name": "查看数值", "description": "允许查看数值列表" }
    }
}

Demo

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.7 83 8/1/2026
1.1.7 85 7/31/2026
1.0.7 87 7/31/2026
1.0.6 325 1/20/2024
1.0.5 512 12/3/2022
1.0.4 578 10/24/2022
1.0.3 557 10/22/2022
1.0.2 568 10/22/2022
1.0.1 610 10/21/2022
1.0.0 544 10/18/2022