#### [Abblix\.Oidc\.Server](https://www.abblix.com/docs/api/abblix-oidc-server 'index')
### [Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests')

## 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&lt;TValidator&gt;\(this IServiceCollection, string\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.ServiceCollectionExtensions#Abblix.Oidc.Server.Features.RichAuthorizationRequests.ServiceCollectionExtensions.AddAuthorizationDetailValidator_TValidator_(thisMicrosoft.Extensions.DependencyInjection.IServiceCollection,string) 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.ServiceCollectionExtensions\.AddAuthorizationDetailValidator\<TValidator\>\(this Microsoft\.Extensions\.DependencyInjection\.IServiceCollection, string\)'); the
composite [IAuthorizationDetailsPolicy](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailsPolicy 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailsPolicy') dispatches each request entry to
the implementation keyed by the entry's `type` value\.

```csharp
public interface IAuthorizationDetailValidator
```

### Remarks
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 {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.Type}

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\.

```csharp
string Type { get; }
```

#### Property Value
[System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String')
### Methods

## IAuthorizationDetailValidator\.BuildConsentDescriptorAsync\(AuthorizationDetail, ClientInfo, CancellationToken\) Method {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.BuildConsentDescriptorAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken)}

Optional: produces a host\-renderable [AuthorizationDetailDescriptor](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.AuthorizationDetailDescriptor 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.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](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail#Abblix.Jwt.AuthorizationDetail.Json 'Abblix\.Jwt\.AuthorizationDetail\.Json')\. Validators that override this should
extract the structured payload from [Json](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail#Abblix.Jwt.AuthorizationDetail.Json 'Abblix\.Jwt\.AuthorizationDetail\.Json') and project it to
the descriptor's Title / Summary / Details shape\.

```csharp
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](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail 'Abblix\.Jwt\.AuthorizationDetail') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.BuildConsentDescriptorAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).detail}

The entry to describe\. Already passed
            [ValidateAsync\(AuthorizationDetail, ClientInfo, CancellationToken\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken) 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailValidator\.ValidateAsync\(Abblix\.Jwt\.AuthorizationDetail, Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo, System\.Threading\.CancellationToken\)'), so the per\-type schema is satisfied\.

###### `client` [ClientInfo](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.ClientInformation.ClientInfo 'Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.BuildConsentDescriptorAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).client}

The requesting client, for descriptions that vary by client metadata
            \(e\.g\. branding, locale\)\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.BuildConsentDescriptorAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).cancellationToken}

Cancellation token\.

#### Returns
[System\.Threading\.Tasks\.Task&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[AuthorizationDetailDescriptor](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.AuthorizationDetailDescriptor 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.AuthorizationDetailDescriptor')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
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 {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken)}

Validates a single authorization\-detail entry against this validator's per\-type schema
and any per\-client policy the implementation chooses to enforce\.

```csharp
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](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail 'Abblix\.Jwt\.AuthorizationDetail') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).detail}

The entry to validate\. Its [Type](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail#Abblix.Jwt.AuthorizationDetail.Type 'Abblix\.Jwt\.AuthorizationDetail\.Type')
            matches this validator's [Type](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.Type 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailValidator\.Type'); the per\-type schema lives in the raw
            [Json](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail#Abblix.Jwt.AuthorizationDetail.Json 'Abblix\.Jwt\.AuthorizationDetail\.Json') object alongside the RFC 9396 §2\.2
            standardised members where applicable\.

###### `client` [ClientInfo](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.ClientInformation.ClientInfo 'Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).client}

The client that submitted the request, for policy decisions that
            depend on per\-client allowlists or registered metadata\.

###### `token` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).token}

Cancellation token\.

#### Returns
[System\.Threading\.Tasks\.Task&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[Abblix\.Utils\.Result&lt;](https://www.abblix.com/docs/api/abblix-utils/Abblix.Utils.Result_TSuccess_TFailure_ 'Abblix\.Utils\.Result\`2')[AuthorizationDetail](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail 'Abblix\.Jwt\.AuthorizationDetail')[,](https://www.abblix.com/docs/api/abblix-utils/Abblix.Utils.Result_TSuccess_TFailure_ 'Abblix\.Utils\.Result\`2')[OidcError](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Common.OidcError 'Abblix\.Oidc\.Server\.Common\.OidcError')[&gt;](https://www.abblix.com/docs/api/abblix-utils/Abblix.Utils.Result_TSuccess_TFailure_ 'Abblix\.Utils\.Result\`2')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
The validated \(and possibly normalised\) detail on success, or a
            [OidcError](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Common.OidcError 'Abblix\.Oidc\.Server\.Common\.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 {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateGrantedAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken)}

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\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken) 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailValidator\.ValidateAsync\(Abblix\.Jwt\.AuthorizationDetail, Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo, System\.Threading\.CancellationToken\)'), so a
type that does not enrich answers the same question in both phases\.

```csharp
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](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail 'Abblix\.Jwt\.AuthorizationDetail') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateGrantedAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).detail}

The granted entry, whose [Type](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail#Abblix.Jwt.AuthorizationDetail.Type 'Abblix\.Jwt\.AuthorizationDetail\.Type') matches
            this validator's [Type](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.Type 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailValidator\.Type')\.

###### `client` [ClientInfo](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.ClientInformation.ClientInfo 'Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateGrantedAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).client}

The client the grant is being issued to\.

###### `token` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateGrantedAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken).token}

Cancellation token\.

#### Returns
[System\.Threading\.Tasks\.Task&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[Abblix\.Utils\.Result&lt;](https://www.abblix.com/docs/api/abblix-utils/Abblix.Utils.Result_TSuccess_TFailure_ 'Abblix\.Utils\.Result\`2')[AuthorizationDetail](https://www.abblix.com/docs/api/abblix-jwt/Abblix.Jwt.AuthorizationDetail 'Abblix\.Jwt\.AuthorizationDetail')[,](https://www.abblix.com/docs/api/abblix-utils/Abblix.Utils.Result_TSuccess_TFailure_ 'Abblix\.Utils\.Result\`2')[OidcError](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Common.OidcError 'Abblix\.Oidc\.Server\.Common\.OidcError')[&gt;](https://www.abblix.com/docs/api/abblix-utils/Abblix.Utils.Result_TSuccess_TFailure_ 'Abblix\.Utils\.Result\`2')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
The validated \(and possibly normalised\) detail on success, or an
            [OidcError](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Common.OidcError 'Abblix\.Oidc\.Server\.Common\.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\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken) 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailValidator\.ValidateAsync\(Abblix\.Jwt\.AuthorizationDetail, Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo, System\.Threading\.CancellationToken\)') keeps refusing it from a client.

An override MUST still refuse everything [ValidateAsync\(AuthorizationDetail, ClientInfo, CancellationToken\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator#Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailValidator.ValidateAsync(Abblix.Jwt.AuthorizationDetail,Abblix.Oidc.Server.Features.ClientInformation.ClientInfo,System.Threading.CancellationToken) 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailValidator\.ValidateAsync\(Abblix\.Jwt\.AuthorizationDetail, Abblix\.Oidc\.Server\.Features\.ClientInformation\.ClientInfo, System\.Threading\.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.
