Skip to content
bitzorcas
中EN

Reference

Fine-Grained Resource-Action Authorization: IAuthorizedRequest Guide

Say goodbye to hardcoded role explosion! Master the BitzOrcas.Modern Resource-Action authorization model with IAuthorizedRequest contracts and dynamic evaluation.

Last updated

Traditional role-based security frequently leads to “Role Explosion”:

  • Handlers cluttered with brittle attributes like [Authorize(Roles = "Admin,SuperAdmin,Manager")], requiring sweeping code changes whenever a new business role is introduced;
  • Inability to enforce granular action controls (e.g. allowing reports to be viewed but forbidding export; allowing draft editing but forbidding publishing).

BitzOrcas.Modern implements a Resource-Action fine-grained authorization model: Request contracts declare IAuthorizedRequest, evaluated in microseconds by AuthorizationPipelineBehavior against the user’s dynamic permission matrix.

Resource-Action Authorization Lifecycle

AuthorizedDenied

1. Inbound Request (Implements IAuthorizedRequest)

2. AuthorizationPipelineBehavior

3. IAuthorizationDecisionService (Evaluates Resource + Action Permissions)

4. Execute Target Handler

5. Short-Circuit Result.Failure(403 Forbidden)


Step 1: Declaring Resource and Action on Contracts

Have Commands or Queries implement IAuthorizedRequest:

ExportFinancialReportQuery.cs: Declaring Resource & Action
using BitzOrcas.Application.Abstractions.Authorization;
using BitzOrcas.Domain.Results;
using Mediator;
namespace BitzOrcas.Finance.Contracts.Queries;
public sealed record ExportFinancialReportQuery(
string ReportYear) : IQuery<Result<byte[]>>, IAuthorizedRequest
{
// ① Target protected resource
public ResourceDescriptor Resource { get; } = new("finance", "report");
// ② Specific business action required for this request
public AuthorizationAction Action { get; } = AuthorizationAction.Export;
}

Step 2: Automated Pipeline Decision Guard

The pipeline evaluates decisions before entering business handlers:

AuthorizationPipelineBehavior.cs: Authorization Pipeline Guard
using System.Threading;
using System.Threading.Tasks;
using BitzOrcas.Domain.Results;
public static class AuthorizationErrors
{
public static readonly Error PermissionDenied =
Error.Forbidden("Auth.PermissionDenied", "Current user is not authorized to execute the specified operation.");
}
public sealed class AuthorizationPipelineBehavior<TRequest, TResponse>(
IAuthorizationDecisionService decisionService,
ICurrentUser currentUser) : IPipelineBehavior<TRequest, TResponse>
where TRequest : IAuthorizedRequest
{
public async ValueTask<TResponse> Handle(
TRequest message,
CancellationToken cancellationToken,
MessageHandlerDelegate<TRequest, TResponse> next)
{
// 1. Evaluate whether active user possesses permission for Resource + Action
var isAuthorized = await decisionService.HasPermissionAsync(
currentUser.UserId,
message.Resource,
message.Action,
cancellationToken);
if (!isAuthorized)
{
// 2. Denied: short-circuit with 403 Forbidden
return (TResponse)(object)Result.Failure(
AuthorizationErrors.PermissionDenied.WithDescription(
$"User is not authorized to execute {message.Resource.Name}:{message.Action}."));
}
// 3. Authorized: proceed to business handler
return await next(message, cancellationToken);
}
}

Summary

Resource-Action authorization decouples security from business handlers:

  • Zero Hardcoded Roles: Code defines operations; roles and permissions are configured dynamically in the admin console;
  • Granular Controls: Precise control over Create, Read, Update, Delete, Export, and Approve actions;
  • Audit-Ready: Unauthorized attempts automatically generate security alerts.

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%