Authorization Core
A comprehensive, modular authorization system built with .NET 9, designed to provide flexible and scalable access control for ASP.NET Core applications.
๐ฏ Purposeโ
The Authorization.Core module provides a complete authorization system based on the Resource-Action-Permission model:
- Flexible Permission System with types and categories
- Resource-Based Access Control with granular action permissions
- Hierarchical Authorization with configurable permission types
- High-Performance APIs using FastEndpoints
- Clean Architecture with full separation of concerns
- Comprehensive Testing with 54+ unit tests
๐ฆ Installationโ
# Core abstractions and interfaces
dotnet add package MasLazu.AspNet.Authorization.Core.Abstraction
# Domain entities
dotnet add package MasLazu.AspNet.Authorization.Core.Domain
# Business logic implementations
dotnet add package MasLazu.AspNet.Authorization.Core
# Database implementation
dotnet add package MasLazu.AspNet.Authorization.Core.EfCore
# API endpoints
dotnet add package MasLazu.AspNet.Authorization.Core.Endpoint
โ๏ธ Configurationโ
1. Add Servicesโ
// Program.cs
using MasLazu.AspNet.Authorization.Core.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add authorization services
builder.Services.AddAuthorizationCoreApplicationServices();
builder.Services.AddAuthorizationCoreApplicationUtils();
// Add database context
builder.Services.AddAuthorizationCoreEntityFrameworkCore();
builder.Services.AddDbContext<AuthorizationCoreDbContext>(options =>
options.UseSqlServer(connectionString));
var app = builder.Build();
// Configure endpoints
app.UseAuthorizationCoreEndpoints();
2. Database Migrationโ
dotnet ef migrations add InitialCreate --project MasLazu.AspNet.Authorization.Core.EfCore
dotnet ef database update
3. Dependency Injectionโ
public class AuthorizationController : ControllerBase
{
private readonly IActionService _actionService;
private readonly IPermissionService _permissionService;
private readonly IResourceService _resourceService;
public AuthorizationController(
IActionService actionService,
IPermissionService permissionService,
IResourceService resourceService)
{
_actionService = actionService;
_permissionService = permissionService;
_resourceService = resourceService;
}
}
๐๏ธ Core Conceptsโ
Actionsโ
Actions represent system operations that can be performed:
// Examples of actions
var readAction = new CreateActionRequest
{
Code = "READ",
Name = "Read"
};
var writeAction = new CreateActionRequest
{
Code = "WRITE",
Name = "Write"
};
var deleteAction = new CreateActionRequest
{
Code = "DELETE",
Name = "Delete"
};
Resourcesโ
Resources represent protected entities or features in your system:
// Examples of resources
var userResource = new CreateResourceRequest
{
Code = "USER",
Name = "User Management"
};
var reportResource = new CreateResourceRequest
{
Code = "REPORT",
Name = "System Reports"
};
Permission Typesโ
Permission Types categorize permissions for better organization:
// Examples of permission types
var systemType = new CreatePermissionTypeRequest
{
Code = "SYSTEM",
Name = "System Permissions"
};
var userType = new CreatePermissionTypeRequest
{
Code = "USER",
Name = "User Permissions"
};
Permissionsโ
Permissions combine actions with resources and types:
// Create a permission
var permission = new CreatePermissionRequest
{
Code = "USER_READ",
Name = "Read Users",
Description = "Permission to read user data",
TypeCode = "SYSTEM"
};
Resource Actionsโ
Resource Actions link available actions to specific resources:
// Link READ action to USER resource
var resourceAction = new CreateResourceActionRequest
{
ResourceCode = "USER",
ActionCode = "READ"
};
๐ Data Modelโ
๐ Usage Examplesโ
1. Setting Up Basic Authorizationโ
public class AuthorizationSetupService
{
private readonly IActionService _actionService;
private readonly IResourceService _resourceService;
private readonly IPermissionTypeService _permissionTypeService;
private readonly IPermissionService _permissionService;
private readonly IResourceActionService _resourceActionService;
public async Task SetupBasicAuthorizationAsync(Guid userId)
{
// 1. Create actions
var readAction = await _actionService.CreateAsync(userId, new CreateActionRequest
{
Code = "READ",
Name = "Read"
});
var writeAction = await _actionService.CreateAsync(userId, new CreateActionRequest
{
Code = "WRITE",
Name = "Write"
});
// 2. Create resources
var userResource = await _resourceService.CreateAsync(userId, new CreateResourceRequest
{
Code = "USER",
Name = "User Management"
});
// 3. Create permission types
var systemType = await _permissionTypeService.CreateAsync(userId, new CreatePermissionTypeRequest
{
Code = "SYSTEM",
Name = "System Permissions"
});
// 4. Link actions to resources
await _resourceActionService.CreateAsync(userId, new CreateResourceActionRequest
{
ResourceCode = "USER",
ActionCode = "READ"
});
await _resourceActionService.CreateAsync(userId, new CreateResourceActionRequest
{
ResourceCode = "USER",
ActionCode = "WRITE"
});
// 5. Create permissions
await _permissionService.CreateAsync(userId, new CreatePermissionRequest
{
Code = "USER_READ",
Name = "Read Users",
Description = "Permission to read user data",
TypeCode = "SYSTEM"
});
await _permissionService.CreateAsync(userId, new CreatePermissionRequest
{
Code = "USER_WRITE",
Name = "Write Users",
Description = "Permission to create/update user data",
TypeCode = "SYSTEM"
});
}
}
2. Querying Permissionsโ
public class PermissionQueryService
{
private readonly IPermissionService _permissionService;
private readonly IResourceActionService _resourceActionService;
public async Task<bool> UserCanPerformActionAsync(string resourceCode, string actionCode)
{
// Check if action is allowed for resource
var request = new PaginationRequest
{
Filters = new List<Filter>
{
new() { Field = "resourceCode", Operator = "=", Value = resourceCode },
new() { Field = "actionCode", Operator = "=", Value = actionCode }
}
};
var result = await _resourceActionService.GetPaginatedAsync(Guid.Empty, request);
return result.Items.Any();
}
public async Task<List<PermissionDto>> GetSystemPermissionsAsync()
{
var request = new PaginationRequest
{
Filters = new List<Filter>
{
new() { Field = "typeCode", Operator = "=", Value = "SYSTEM" }
}
};
var result = await _permissionService.GetPaginatedAsync(Guid.Empty, request);
return result.Items;
}
}
3. Custom Authorization Middlewareโ
public class ResourceActionAuthorizationMiddleware
{
private readonly RequestDelegate _next;
private readonly IResourceActionService _resourceActionService;
public ResourceActionAuthorizationMiddleware(
RequestDelegate next,
IResourceActionService resourceActionService)
{
_next = next;
_resourceActionService = resourceActionService;
}
public async Task InvokeAsync(HttpContext context)
{
// Extract resource and action from route/headers
var resource = context.Request.Headers["X-Resource"].FirstOrDefault();
var action = context.Request.Headers["X-Action"].FirstOrDefault();
if (!string.IsNullOrEmpty(resource) && !string.IsNullOrEmpty(action))
{
var hasPermission = await CheckPermissionAsync(resource, action);
if (!hasPermission)
{
context.Response.StatusCode = 403;
await context.Response.WriteAsync("Access denied");
return;
}
}
await _next(context);
}
private async Task<bool> CheckPermissionAsync(string resource, string action)
{
var request = new PaginationRequest
{
Filters = new List<Filter>
{
new() { Field = "resourceCode", Operator = "=", Value = resource },
new() { Field = "actionCode", Operator = "=", Value = action }
}
};
var result = await _resourceActionService.GetPaginatedAsync(Guid.Empty, request);
return result.Items.Any();
}
}
// Register middleware
app.UseMiddleware<ResourceActionAuthorizationMiddleware>();
๐ API Referenceโ
Actions Endpointsโ
Method | Endpoint | Description |
---|---|---|
GET | /api/v1/actions | Get paginated actions |
GET | /api/v1/actions/{id} | Get action by ID |
POST | /api/v1/actions | Create new action |
PUT | /api/v1/actions/{id} | Update existing action |
DELETE | /api/v1/actions/{id} | Delete action |
Resources Endpointsโ
Method | Endpoint | Description |
---|---|---|
GET | /api/v1/resources | Get paginated resources |
GET | /api/v1/resources/{id} | Get resource by ID |
POST | /api/v1/resources | Create new resource |
PUT | /api/v1/resources/{id} | Update existing resource |
DELETE | /api/v1/resources/{id} | Delete resource |
Permissions Endpointsโ
Method | Endpoint | Description |
---|---|---|
GET | /api/v1/permissions | Get paginated permissions |
GET | /api/v1/permissions/{id} | Get permission by ID |
POST | /api/v1/permissions | Create new permission |
PUT | /api/v1/permissions/{id} | Update existing permission |
DELETE | /api/v1/permissions/{id} | Delete permission |
Permission Types Endpointsโ
Method | Endpoint | Description |
---|---|---|
GET | /api/v1/permission-types | Get paginated permission types |
GET | /api/v1/permission-types/{id} | Get permission type by ID |
POST | /api/v1/permission-types | Create new permission type |
PUT | /api/v1/permission-types/{id} | Update existing permission type |
DELETE | /api/v1/permission-types/{id} | Delete permission type |
Resource Actions Endpointsโ
Method | Endpoint | Description |
---|---|---|
GET | /api/v1/resource-actions | Get paginated resource actions |
GET | /api/v1/resource-actions/{id} | Get resource action by ID |
POST | /api/v1/resource-actions | Create new resource action |
PUT | /api/v1/resource-actions/{id} | Update existing resource action |
DELETE | /api/v1/resource-actions/{id} | Delete resource action |
๐ Advanced Featuresโ
Pagination and Filteringโ
All endpoints support advanced pagination and filtering:
# Get permissions with pagination
GET /api/v1/permissions?page=1&pageSize=20
# Filter permissions by type
GET /api/v1/permissions?filters[0].field=typeCode&filters[0].operator=eq&filters[0].value=SYSTEM
# Sort permissions by name
GET /api/v1/permissions?orderBy[0].field=name&orderBy[0].desc=false
Validationโ
The module includes comprehensive validation:
- Field Existence: Validates that filter/sort fields exist
- Operator Compatibility: Ensures operators match field types
- Required Fields: Validates required properties on requests
- Unique Constraints: Prevents duplicate codes
Property Mappingโ
Dynamic property mapping for LINQ queries:
// Available properties for filtering and sorting
var actionProperties = new[] { "id", "code", "name", "createdAt", "updatedAt" };
var resourceProperties = new[] { "id", "code", "name", "createdAt", "updatedAt" };
var permissionProperties = new[] { "id", "code", "name", "description", "typeCode", "createdAt", "updatedAt" };
๐ Project Structureโ
MasLazu.AspNet.Authorization.Core/
โโโ src/
โ โโโ MasLazu.AspNet.Authorization.Core.Abstraction/
โ โ โโโ Interfaces/
โ โ โ โโโ IActionService.cs
โ โ โ โโโ IPermissionService.cs
โ โ โ โโโ IPermissionTypeService.cs
โ โ โ โโโ IResourceService.cs
โ โ โ โโโ IResourceActionService.cs
โ โ โโโ Models/
โ โ โ โโโ ActionDto.cs
โ โ โ โโโ CreateActionRequest.cs
โ โ โ โโโ UpdateActionRequest.cs
โ โ โ โโโ PermissionDto.cs
โ โ โ โโโ CreatePermissionRequest.cs
โ โ โ โโโ UpdatePermissionRequest.cs
โ โ โ โโโ ResourceDto.cs
โ โ โ โโโ CreateResourceRequest.cs
โ โ โ โโโ UpdateResourceRequest.cs
โ โ โ โโโ PermissionTypeDto.cs
โ โ โ โโโ CreatePermissionTypeRequest.cs
โ โ โ โโโ UpdatePermissionTypeRequest.cs
โ โ โ โโโ ResourceActionDto.cs
โ โ โ โโโ CreateResourceActionRequest.cs
โ โ โ โโโ UpdateResourceActionRequest.cs
โ โ โโโ MasLazu.AspNet.Authorization.Core.Abstraction.csproj
โ โ
โ โโโ MasLazu.AspNet.Authorization.Core.Domain/
โ โ โโโ Entities/
โ โ โ โโโ Action.cs
โ โ โ โโโ Permission.cs
โ โ โ โโโ PermissionType.cs
โ โ โ โโโ Resource.cs
โ โ โ โโโ ResourceAction.cs
โ โ โโโ MasLazu.AspNet.Authorization.Core.Domain.csproj
โ โ
โ โโโ MasLazu.AspNet.Authorization.Core/
โ โ โโโ Services/
โ โ โ โโโ ActionService.cs
โ โ โ โโโ PermissionService.cs
โ โ โ โโโ PermissionTypeService.cs
โ โ โ โโโ ResourceService.cs
โ โ โ โโโ ResourceActionService.cs
โ โ โโโ Utils/
โ โ โ โโโ ActionEntityPropertyMap.cs
โ โ โ โโโ PermissionEntityPropertyMap.cs
โ โ โ โโโ PermissionTypeEntityPropertyMap.cs
โ โ โ โโโ ResourceEntityPropertyMap.cs
โ โ โ โโโ ResourceActionEntityPropertyMap.cs
โ โ โโโ Validators/
โ โ โ โโโ CreateActionRequestValidator.cs
โ โ โ โโโ UpdateActionRequestValidator.cs
โ โ โ โโโ CreatePermissionRequestValidator.cs
โ โ โ โโโ UpdatePermissionRequestValidator.cs
โ โ โ โโโ CreateResourceRequestValidator.cs
โ โ โ โโโ UpdateResourceRequestValidator.cs
โ โ โ โโโ CreatePermissionTypeRequestValidator.cs
โ โ โ โโโ UpdatePermissionTypeRequestValidator.cs
โ โ โ โโโ CreateResourceActionRequestValidator.cs
โ โ โ โโโ UpdateResourceActionRequestValidator.cs
โ โ โโโ Extensions/
โ โ โ โโโ AuthorizationCoreApplicationServiceExtension.cs
โ โ โ โโโ AuthorizationCoreApplicationUtilExtension.cs
โ โ โ โโโ AuthorizationCoreApplicationValidatorExtension.cs
โ โ โโโ MasLazu.AspNet.Authorization.Core.csproj
โ โ
โ โโโ MasLazu.AspNet.Authorization.Core.EfCore/
โ โ โโโ Configurations/
โ โ โ โโโ ActionConfiguration.cs
โ โ โ โโโ PermissionConfiguration.cs
โ โ โ โโโ PermissionTypeConfiguration.cs
โ โ โ โโโ ResourceConfiguration.cs
โ โ โ โโโ ResourceActionConfiguration.cs
โ โ โโโ Data/
โ โ โ โโโ AuthorizationCoreDbContext.cs
โ โ โโโ Extensions/
โ โ โ โโโ ServiceCollectionExtensions.cs
โ โ โโโ MasLazu.AspNet.Authorization.Core.EfCore.csproj
โ โ
โ โโโ MasLazu.AspNet.Authorization.Core.Endpoint/
โ โโโ EndpointGroups/
โ โ โโโ ActionsEndpointGroup.cs
โ โ โโโ PermissionsEndpointGroup.cs
โ โ โโโ PermissionTypesEndpointGroup.cs
โ โ โโโ ResourcesEndpointGroup.cs
โ โ โโโ ResourceActionsEndpointGroup.cs
โ โโโ Endpoints/
โ โ โโโ Actions/
โ โ โ โโโ GetActionByIdEndpoint.cs
โ โ โ โโโ GetActionsPaginatedEndpoint.cs
โ โ โโโ Permissions/
โ โ โ โโโ GetPermissionByIdEndpoint.cs
โ โ โ โโโ GetPermissionsPaginatedEndpoint.cs
โ โ โโโ PermissionTypes/
โ โ โ โโโ GetPermissionTypeByIdEndpoint.cs
โ โ โ โโโ GetPermissionTypesPaginatedEndpoint.cs
โ โ โโโ Resources/
โ โ โ โโโ GetResourceByIdEndpoint.cs
โ โ โ โโโ GetResourcesPaginatedEndpoint.cs
โ โ โโโ ResourceActions/
โ โ โโโ GetResourceActionByIdEndpoint.cs
โ โ โโโ GetResourceActionsPaginatedEndpoint.cs
โ โโโ Extensions/
โ โ โโโ AuthorizationCoreEndpointExtension.cs
โ โโโ MasLazu.AspNet.Authorization.Core.Endpoint.csproj
โ
โโโ test/ # Comprehensive Unit Tests
โ โโโ MasLazu.AspNet.Authorization.Core.Abstraction.Tests/
โ โโโ MasLazu.AspNet.Authorization.Core.Domain.Tests/
โ โโโ MasLazu.AspNet.Authorization.Core.Tests/
โ โโโ MasLazu.AspNet.Authorization.Core.EfCore.Tests/
โ โโโ MasLazu.AspNet.Authorization.Core.Endpoint.Tests/
โ
โโโ MasLazu.AspNet.Authorization.Core.sln
๐ Dependenciesโ
<!-- Core Framework -->
<PackageReference Include="MasLazu.AspNet.Framework.Application" />
<PackageReference Include="MasLazu.AspNet.Framework.Domain" />
<PackageReference Include="MasLazu.AspNet.Framework.EfCore" />
<PackageReference Include="MasLazu.AspNet.Framework.Endpoint" />
<!-- Validation & Mapping -->
<PackageReference Include="FluentValidation" />
<PackageReference Include="Mapster" />
<!-- Database -->
<PackageReference Include="Microsoft.EntityFrameworkCore" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<!-- API Framework -->
<PackageReference Include="FastEndpoints" />
๐งช Testingโ
The module includes 54+ comprehensive unit tests:
# Run all tests
dotnet test
# Run specific test project
dotnet test test/MasLazu.AspNet.Authorization.Core.Tests/
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
๐ Best Practicesโ
1. Permission Namingโ
Use consistent naming conventions:
// Format: {RESOURCE}_{ACTION}
var permissions = new[]
{
"USER_READ", // Can read user data
"USER_WRITE", // Can create/update users
"USER_DELETE", // Can delete users
"REPORT_READ", // Can read reports
"REPORT_WRITE" // Can create/update reports
};
2. Resource Organizationโ
Group related functionality:
var resources = new[]
{
"USER", // User management
"ROLE", // Role management
"REPORT", // Reporting system
"SETTING", // System settings
"AUDIT" // Audit logs
};
3. Permission Typesโ
Use hierarchical organization:
var permissionTypes = new[]
{
"SYSTEM", // System-level permissions
"MODULE", // Module-specific permissions
"USER", // User-level permissions
"GUEST" // Guest permissions
};
๐ Migration Guideโ
From Custom Authorizationโ
- Map existing permissions to the new model
- Create actions for your operations
- Define resources for your entities
- Set up resource-action links
- Migrate permission assignments
Database Schemaโ
The module creates these tables:
actions
- System operationsresources
- Protected entitiespermission_types
- Permission categoriespermissions
- Combined permissionsresource_actions
- Resource-action mappings
๐ค Integration Examplesโ
With Authentication.Coreโ
// Combine with user authentication
public class AuthorizedUserService
{
private readonly IUserService _userService;
private readonly IPermissionService _permissionService;
public async Task<bool> UserHasPermissionAsync(Guid userId, string permissionCode)
{
var user = await _userService.GetByIdAsync(userId, userId);
if (user == null) return false;
// Check if user has specific permission
// Implementation depends on your user-permission mapping
return await CheckUserPermissionAsync(userId, permissionCode);
}
}
With Custom Middlewareโ
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class RequirePermissionAttribute : Attribute
{
public string Resource { get; }
public string Action { get; }
public RequirePermissionAttribute(string resource, string action)
{
Resource = resource;
Action = action;
}
}
// Usage
[RequirePermission("USER", "READ")]
public async Task<IActionResult> GetUsers()
{
// Only accessible with USER_READ permission
}
๐ฎ Future Enhancementsโ
- Role-based permissions - Map permissions to roles
- User-permission assignments - Direct user-permission mapping
- Permission inheritance - Hierarchical permission structure
- Conditional permissions - Context-based authorization
- Audit logging - Track permission usage
- Performance optimization - Caching and bulk operations
๐ Supportโ
- Documentation: Authorization Core Guide
- Source Code: GitHub Repository
- Issues: Report Issues
- Discussions: Community Discussions