Class ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>
Pipeline behavior that performs indirect (multi-hop) resource-based authorization. The command identifies a leaf resource via the existing IResourceLoader<TMessage, TResource> infrastructure and declares its final authorization target via IAuthorizeResourceVia<TOwner>; this behavior walks the pre-resolved ResolvedAuthorizationPath from leaf to owner and invokes the command's Authorize(Actor, IReadOnlyList<TOwner>) method against the final list of owners.
public sealed class ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse> : IPipelineBehavior<TMessage, TResponse> where TMessage : IAuthorizeResourceVia<TOwner>, IMessage where TLeaf : class where TResponse : IResult, IFailureFactory<TResponse>
Type Parameters
TMessageThe message type, constrained to IAuthorizeResourceVia<TOwner>.
TLeafThe leaf resource type identified by the message.
TOwnerThe owner resource type at the end of the navigation chain.
TResponseThe response type, constrained to IResult and IFailureFactory<TSelf>.
- Inheritance
-
ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>
- Implements
-
IPipelineBehavior<TMessage, TResponse>
- Inherited Members
- Extension Methods
Remarks
Failure semantics:
- Leaf load failure — propagates under Propagate; root NotFound, Gone, Forbidden, and AuthenticationRequired normalize to the public NotFound under HideAsNotFound. Other leaf errors are unchanged.
- Intermediate / owner load failure — collapsed to Error.Forbidden to avoid leaking existence of related resources whose presence/absence the actor may not be authorized to learn.
- Empty result at any hop (singular extract returning 0 IDs or plural extract returning 0 IDs) — short-circuits to Error.Forbidden without calling Authorize(Actor, IReadOnlyList<TOwner>).
Constructors
ResourceAuthorizationViaBehavior(IActorProvider, IServiceProvider, ResolvedAuthorizationPath)
Initializes a new instance of the ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse> class.
public ResourceAuthorizationViaBehavior(IActorProvider actorProvider, IServiceProvider serviceProvider, ResolvedAuthorizationPath path)
Parameters
actorProviderIActorProviderProvider used to resolve the current actor.
serviceProviderIServiceProviderThe request-scoped service provider used to resolve the leaf loader and per-hop loaders.
pathResolvedAuthorizationPathThe pre-resolved authorization path from leaf to owner.
Exceptions
- ArgumentNullException
Thrown when any argument is null.
- ArgumentException
Thrown when
pathdoes not agree with the behavior's generic arguments — specifically when MessageType is notTMessage, LeafType is notTLeaf, or OwnerType is notTOwner. This guards against a single ResolvedAuthorizationPath being shared across multiple via-authorized commands via DI; the typed-registration path uses ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse> to prevent that misuse statically, and this constructor's defense applies if a consumer constructs the behavior manually.
ResourceAuthorizationViaBehavior(IActorProvider, IServiceProvider, ResolvedAuthorizationPath, IOptions<ResourceAuthorizationOptions>?, ILogger<ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>>?)
Initializes a new instance of the ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse> class with exposure-policy options and diagnostics.
public ResourceAuthorizationViaBehavior(IActorProvider actorProvider, IServiceProvider serviceProvider, ResolvedAuthorizationPath path, IOptions<ResourceAuthorizationOptions>? options, ILogger<ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>>? logger = null)
Parameters
actorProviderIActorProviderProvider used to resolve the current actor.
serviceProviderIServiceProviderThe request-scoped service provider used to resolve the leaf loader and per-hop loaders.
pathResolvedAuthorizationPathThe pre-resolved authorization path from leaf to owner.
optionsIOptions<ResourceAuthorizationOptions>Per-resource exposure-policy options resolved from DI.
loggerILogger<ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>>Logger used to emit the
ExistenceHiddenevent when a translation occurs.
Exceptions
- ArgumentNullException
Thrown when any required argument is null.
- ArgumentException
Same shape as the parameterless overload — see remarks on path agreement.
ResourceAuthorizationViaBehavior(IActorProvider, IServiceProvider, ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse>)
Initializes a new instance using a ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse> for DI-friendly typed registration. The holder is registered as a closed-generic singleton per via-authorized command; DI naturally disambiguates it per command, eliminating the need for factory-style descriptor registration.
public ResourceAuthorizationViaBehavior(IActorProvider actorProvider, IServiceProvider serviceProvider, ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse> pathHolder)
Parameters
actorProviderIActorProviderProvider used to resolve the current actor.
serviceProviderIServiceProviderThe request-scoped service provider used to resolve the leaf loader and per-hop loaders.
pathHolderResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse>The closed-generic carrier for the resolved path.
Exceptions
- ArgumentNullException
Thrown when any argument is null.
ResourceAuthorizationViaBehavior(IActorProvider, IServiceProvider, ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse>, IOptions<ResourceAuthorizationOptions>?, ILogger<ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>>?)
Initializes a new instance using a ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse> for DI-friendly typed registration. Includes exposure-policy options and diagnostics.
public ResourceAuthorizationViaBehavior(IActorProvider actorProvider, IServiceProvider serviceProvider, ResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse> pathHolder, IOptions<ResourceAuthorizationOptions>? options, ILogger<ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>>? logger = null)
Parameters
actorProviderIActorProviderProvider used to resolve the current actor.
serviceProviderIServiceProviderThe request-scoped service provider used to resolve the leaf loader and per-hop loaders.
pathHolderResolvedAuthorizationPathHolder<TMessage, TLeaf, TOwner, TResponse>The closed-generic carrier for the resolved path.
optionsIOptions<ResourceAuthorizationOptions>Per-resource exposure-policy options resolved from DI. Null defaults to the always-propagate behavior.
loggerILogger<ResourceAuthorizationViaBehavior<TMessage, TLeaf, TOwner, TResponse>>Logger used to emit the
ExistenceHiddenevent when NotFound, Gone, Forbidden, or AuthenticationRequired is normalized to the public NotFound. Null defaults to Instance.
Exceptions
- ArgumentNullException
Thrown when any required argument is null.
Methods
Handle(TMessage, MessageHandlerDelegate<TMessage, TResponse>, CancellationToken)
public ValueTask<TResponse> Handle(TMessage message, MessageHandlerDelegate<TMessage, TResponse> next, CancellationToken cancellationToken)
Parameters
messageTMessagenextMessageHandlerDelegate<TMessage, TResponse>cancellationTokenCancellationToken
Returns
- ValueTask<TResponse>