dotnet-permission-authorization
Implements permission-based authorization with custom attributes, policy providers, and authorization handlers. Provides granular access control beyond simple role-based authorization.
git clone --depth 1 https://github.com/ronnythedev/dotnet-clean-architecture-skills /tmp/dotnet-permission-authorization && cp -r /tmp/dotnet-permission-authorization/skills/13-dotnet-permission-authorization ~/.claude/skills/dotnet-permission-authorizationSKILL.md
# Permission-Based Authorization Setup
## Overview
This skill implements fine-grained permission-based authorization:
- **Custom [HasPermission] attribute** - Declarative permission requirements
- **Policy provider** - Dynamically creates policies from permissions
- **Authorization handler** - Validates user permissions
- **Claims transformation** - Converts roles to permissions
## Quick Reference
| Component | Purpose |
|-----------|---------|
| `Permissions` | Static permission constants |
| `Roles` | Static role constants |
| `HasPermissionAttribute` | Custom authorize attribute |
| `PermissionAuthorizationHandler` | Validates permissions |
| `PermissionAuthorizationPolicyProvider` | Creates policies dynamically |
| `RoleToPermissionClaimsTransformation` | Maps roles to permissions |
---
## Authorization Structure
```
/Infrastructure/Authorization/
├── Permissions.cs
├── Roles.cs
├── HasPermissionAttribute.cs
├── PermissionRequirement.cs
├── PermissionAuthorizationHandler.cs
├── PermissionAuthorizationPolicyProvider.cs
├── RoleToPermissionClaimsTransformation.cs
└── AuthorizationExtensions.cs
```
---
## Template: Permissions Definition
```csharp
// src/{name}.infrastructure/Authorization/Permissions.cs
namespace {name}.infrastructure.authorization;
/// <summary>
/// All available permissions in the system
/// Format: {resource}:{action}
/// </summary>
public static class Permissions
{
// ═══════════════════════════════════════════════════════════════
// ORGANIZATION PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string OrganizationsRead = "organizations:read";
public const string OrganizationsWrite = "organizations:write";
public const string OrganizationsDelete = "organizations:delete";
public const string OrganizationsManageSettings = "organizations:manage_settings";
// ═══════════════════════════════════════════════════════════════
// USER PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string UsersRead = "users:read";
public const string UsersWrite = "users:write";
public const string UsersDelete = "users:delete";
public const string UsersManageRoles = "users:manage_roles";
// ═══════════════════════════════════════════════════════════════
// DEPARTMENT PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string DepartmentsRead = "departments:read";
public const string DepartmentsWrite = "departments:write";
public const string DepartmentsDelete = "departments:delete";
// ═══════════════════════════════════════════════════════════════
// ASSESSMENT PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string AssessmentsRead = "assessments:read";
public const string AssessmentsWrite = "assessments:write";
public const string AssessmentsSubmit = "assessments:submit";
public const string AssessmentsReview = "assessments:review";
// ═══════════════════════════════════════════════════════════════
// REPORT PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string ReportsRead = "reports:read";
public const string ReportsExport = "reports:export";
public const string ReportsViewSensitive = "reports:view_sensitive";
// ═══════════════════════════════════════════════════════════════
// ADMIN PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string AdminAccess = "admin:access";
public const string AdminManageSystem = "admin:manage_system";
}
```
---
## Template: Roles Definition
```csharp
// src/{name}.infrastructure/Authorization/Roles.cs
namespace {name}.infrastructure.authorization;
/// <summary>
/// All available roles in the system
/// </summary>
public static class Roles
{
public const string SuperAdmin = "SuperAdmin";
public const string Admin = "Admin";
public const string Consultant = "Consultant";
public const string Manager = "Manager";
public const string Associate = "Associate";
public const string Viewer = "Viewer";
}
```
---
## Template: Role-Permission Mapping
```csharp
// src/{name}.infrastructure/Authorization/RolePermissions.cs
namespace {name}.infrastructure.authorization;
/// <summary>
/// Maps roles to their granted permissions
/// </summary>
public static class RolePermissions
{
private static readonly Dictionary<string, HashSet<string>> RolePermissionMap = new()
{
// ═══════════════════════════════════════════════════════════════
// SUPER ADMIN - Full system access
// ═══════════════════════════════════════════════════════════════
[Roles.SuperAdmin] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.OrganizationsWrite,
Permissions.OrganizationsDelete,
Permissions.OrganizationsManageSettings,
Permissions.UsersRead,
Permissions.UsersWrite,
Permissions.UsersDelete,
Permissions.UsersManageRoles,
Permissions.DepartmentsRead,
Permissions.DepartmentsWrite,
Permissions.DepartmentsDelete,
Permissions.AssessmentsRead,
Permissions.AssessmentsWrite,
Permissions.AssessmentsSubmit,
Permissions.AssessmentsReview,
Permissions.ReportsRead,
Permissions.ReportsExport,
Permissions.ReportsViewSensitive,
Permissions.AdminAccess,
Permissions.AdminManageSystem
},
// ═══════════════════════════════════════════════════════════════
// ADMIN - Organization-level admin
// ═══════════════════════════════════════════════════════════════
[Roles.Admin] = new HashSet<string>
{
Permissions.OrganizatioScaffolds a complete .NET solution following Clean Architecture principles with proper layer separation (API, Application, Domain, Infrastructure). Creates project structure, dependency injection setup, and cross-cutting concerns configuration.
Generates CQRS Commands with Handlers, Validators, and Request DTOs following Clean Architecture patterns. Commands represent actions that modify state and return Result types for proper error handling.
Generates CQRS Queries with Handlers and Response DTOs for read operations. Uses Dapper for optimized read queries, bypassing the domain model for better performance.
Generates Domain Entities following DDD principles with factory methods, private setters, domain events, and proper encapsulation. Supports aggregate roots, child entities, and value objects.
Generates Repository interfaces and implementations following the Repository pattern. Provides data access abstraction for aggregate roots with EF Core implementations.
Generates Entity Framework Core configurations using Fluent API. Maps domain entities to database tables with proper relationships, constraints, and conventions.
Generates RESTful API Controllers with proper routing, versioning, authorization, and MediatR integration. Follows REST conventions and Clean Architecture patterns.
Generates Minimal API endpoints following Microsoft's recommended approach. Creates fast, testable HTTP APIs with minimal code using MapGet/MapPost/MapPut/MapDelete. Preferred over controller-based APIs for new projects.