public class Permission : BaseEntity{ /// <summary> /// Unique permission name (e.g., "users.create") /// </summary> public string Name { get; set; } = string.Empty; /// <summary> /// Description of what this permission allows /// </summary> public string? Description { get; set; } /// <summary> /// Module this permission belongs to (e.g., "Users", "Reports") /// </summary> public string Module { get; set; } = string.Empty; /// <summary> /// Whether this permission is currently active /// </summary> public bool IsActive { get; set; } = true; /// <summary> /// Relationship to roles through RolePermission /// </summary> public ICollection<RolePermission> RolePermissions { get; set; } = new List<RolePermission>();}
public class PermissionRequirement : IAuthorizationRequirement{ public string Permission { get; } public PermissionRequirement(string permission) { Permission = permission; }}
public static class Policies{ public const string CanPurge = nameof(CanPurge); public const string CanManageUsers = nameof(CanManageUsers); public const string CanViewReports = nameof(CanViewReports); public const string CanManageRoles = nameof(CanManageRoles);}
public class RolePermission{ public string RoleId { get; set; } = string.Empty; public int PermissionId { get; set; } // Navigation properties public IdentityRole Role { get; set; } = null!; public Permission Permission { get; set; } = null!;}
public class DeleteUserCommandHandler : IRequestHandler<DeleteUserCommand, Result>{ private readonly IUser _currentUser; private readonly IApplicationDbContext _context; public async Task<Result> Handle( DeleteUserCommand request, CancellationToken cancellationToken) { // Check if user has permission if (!_currentUser.HasPermission("users.delete")) { throw new ForbiddenAccessException(); } // Prevent users from deleting themselves if (_currentUser.Id == request.UserId) { return Result.Failure(new[] { "Cannot delete your own account" }); } // Proceed with deletion // ... }}
Check if user owns the resource they’re trying to access:
var document = await _context.Documents .FirstOrDefaultAsync(d => d.Id == request.DocumentId);if (document.OwnerId != _currentUser.Id && !_currentUser.IsInRole("Administrator")){ throw new ForbiddenAccessException();}
Check for module-level or specific permissions:
// Check if user has module-level permission or specific permissionvar hasAccess = _currentUser.HasPermission("users.*") || _currentUser.HasPermission("users.update");if (!hasAccess){ throw new ForbiddenAccessException();}
Combine role and permission checks:
// Admins bypass permission checksif (!_currentUser.IsInRole("Administrator")){ // Regular users need specific permission if (!_currentUser.HasPermission("reports.sensitive")) { throw new ForbiddenAccessException(); }}
Implement time-based access restrictions:
// Only allow access during business hoursvar currentHour = DateTime.UtcNow.Hour;var isBusinessHours = currentHour >= 8 && currentHour < 18;if (!isBusinessHours && !_currentUser.IsInRole("Administrator")){ throw new ForbiddenAccessException("Access only during business hours");}