IAuthorizationDetailValidator Interface
Validates a single RFC 9396 authorization_details entry whose type value matches the
implementation. Hosts register one implementation per supported type via
AddAuthorizationDetailValidator<TValidator>(this IServiceCollection, string); the
composite IAuthorizationDetailsPolicy dispatches each request entry to
the implementation keyed by the entry's type value.
public interface IAuthorizationDetailValidatorRemarks
The library ships no concrete implementations of this interface - each authorization-detail
type (e.g. payment_initiation, consent, OpenID4VC presentation schemas) demands
its own per-type schema and is contributed by the host or a separate package. RFC 9396 §5
requires the AS to refuse any entry whose type is unknown; with zero implementations
registered, every RAR-bearing request is rejected with invalid_authorization_details
and the server still boots cleanly.
Properties
IAuthorizationDetailValidator.Type Property
The authorization-detail type value this validator handles. Used as the DI key
under which the implementation is registered and looked up at request time.
string Type { get; }Property Value
Methods
IAuthorizationDetailValidator.BuildConsentDescriptorAsync(AuthorizationDetail, ClientInfo, CancellationToken) Method
Optional: produces a host-renderable AuthorizationDetailDescriptor describing
what consenting to this entry authorises, so the consent UI can render a meaningful screen
instead of a raw JSON dump. Default returns null; hosts that opt out simply fall back
to displaying Json. Validators that override this should
extract the structured payload from Json and project it to
the descriptor's Title / Summary / Details shape.
System.Threading.Tasks.Task<Abblix.Oidc.Server.Features.RichAuthorizationRequests.AuthorizationDetailDescriptor?> BuildConsentDescriptorAsync(Abblix.Jwt.AuthorizationDetail detail, Abblix.Oidc.Server.Features.ClientInformation.ClientInfo client, System.Threading.CancellationToken cancellationToken);Parameters
detail AuthorizationDetail
The entry to describe. Already passed ValidateAsync(AuthorizationDetail, ClientInfo, CancellationToken), so the per-type schema is satisfied.
client ClientInfo
The requesting client, for descriptions that vary by client metadata (e.g. branding, locale).
cancellationToken System.Threading.CancellationToken
Cancellation token.
Returns
System.Threading.Tasks.Task<AuthorizationDetailDescriptor>
The descriptor on success; null when no structured description is
available and the host should fall back to a JSON-dump rendering.
IAuthorizationDetailValidator.ValidateAsync(AuthorizationDetail, ClientInfo, CancellationToken) Method
Validates a single authorization-detail entry against this validator's per-type schema and any per-client policy the implementation chooses to enforce.
System.Threading.Tasks.Task<Abblix.Utils.Result<Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Common.OidcError>> ValidateAsync(Abblix.Jwt.AuthorizationDetail detail, Abblix.Oidc.Server.Features.ClientInformation.ClientInfo client, System.Threading.CancellationToken token);Parameters
detail AuthorizationDetail
The entry to validate. Its Type matches this validator's Type; the per-type schema lives in the raw Json object alongside the RFC 9396 §2.2 standardised members where applicable.
client ClientInfo
The client that submitted the request, for policy decisions that depend on per-client allowlists or registered metadata.
token System.Threading.CancellationToken
Cancellation token.
Returns
System.Threading.Tasks.Task<Abblix.Utils.Result<AuthorizationDetail,OidcError>>
The validated (and possibly normalised) detail on success, or a
OidcError describing the rejection reason on
failure. RFC 9396 §5 makes the protocol-level error code at the wire
invalid_authorization_details regardless of the underlying reason.
IAuthorizationDetailValidator.ValidateGrantedAsync(AuthorizationDetail, ClientInfo, CancellationToken) Method
Validates a single entry as the consent decision left it, which may carry values the server itself added while the end-user was choosing. Defaults to ValidateAsync(AuthorizationDetail, ClientInfo, CancellationToken), so a type that does not enrich answers the same question in both phases.
System.Threading.Tasks.Task<Abblix.Utils.Result<Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Common.OidcError>> ValidateGrantedAsync(Abblix.Jwt.AuthorizationDetail detail, Abblix.Oidc.Server.Features.ClientInformation.ClientInfo client, System.Threading.CancellationToken token);Parameters
detail AuthorizationDetail
The granted entry, whose Type matches this validator's Type.
client ClientInfo
The client the grant is being issued to.
token System.Threading.CancellationToken
Cancellation token.
Returns
System.Threading.Tasks.Task<Abblix.Utils.Result<AuthorizationDetail,OidcError>>
The validated (and possibly normalised) detail on success, or an
OidcError describing the rejection. A rejection here means the consent decision
escalated beyond what this type permits, which is a host-side defect rather than a client
error.
Remarks
RFC 9396 §7.1 says that "Whether enrichment is allowed and specifics of how it works are
necessarily part of the definition of the respective authorization details type", and in this
library the definition of a type is this validator. Its worked example (Figures 16 and 17) is
an account_information entry whose empty arrays are placeholders the server fills with
the identifiers the user picked.
That shape is one the request-time question may legitimately refuse: RFC 9396 §5 has the server reject an entry that "contains fields with invalid values for the authorization details type", and a type whose definition says the client must not choose the accounts makes a populated placeholder exactly that. Such a type overrides this member so the consent decision's own output is accepted, while ValidateAsync(AuthorizationDetail, ClientInfo, CancellationToken) keeps refusing it from a client.
An override MUST still refuse everything ValidateAsync(AuthorizationDetail, ClientInfo, CancellationToken) refuses, apart from the fields its type declares enrichable. This is the anti-escalation re-check, and the consent decision reaching it has often crossed the browser: what the library still guarantees for an overriding type is only that entries are JSON objects, that their types are known, requested and on the client's allowlist. Everything inside an entry - an amount, an account, a list of locations - is guaranteed by this method and by nothing else. An override that returns its input unconditionally hands a tampered consent decision straight to the issued token.
Note what this method is NOT given: the entry the client originally sent, and the end user who answered. So an enrichable field can be bounded here only by rules that hold on their own - a ceiling, a format, a per-client limit - and not by comparing the value against the request it came from. A type whose enrichment needs that comparison has to make it where both sides are in hand, which today is the consent provider that produced the decision.