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

## ConsentConstraintEnforcer Class

Default [IConsentConstraintEnforcer](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Endpoints.Authorization.IConsentConstraintEnforcer 'Abblix\.Oidc\.Server\.Endpoints\.Authorization\.IConsentConstraintEnforcer')\. Asserts `granted ⊆ requested` for scopes,
resources \(including their nested scopes\) and RFC 9396 `authorization_details`, throwing
when the consent provider returned anything outside the request\.

```csharp
public class ConsentConstraintEnforcer : Abblix.Oidc.Server.Endpoints.Authorization.IConsentConstraintEnforcer
```

Inheritance [System\.Object](https://learn.microsoft.com/en-us/dotnet/api/system.object 'System\.Object') → ConsentConstraintEnforcer

Implements [IConsentConstraintEnforcer](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Endpoints.Authorization.IConsentConstraintEnforcer 'Abblix\.Oidc\.Server\.Endpoints\.Authorization\.IConsentConstraintEnforcer')
### Constructors

## ConsentConstraintEnforcer\(IAuthorizationDetailsPolicy\) Constructor {#Abblix.Oidc.Server.Endpoints.Authorization.ConsentConstraintEnforcer.ConsentConstraintEnforcer(Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailsPolicy)}

Default [IConsentConstraintEnforcer](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Endpoints.Authorization.IConsentConstraintEnforcer 'Abblix\.Oidc\.Server\.Endpoints\.Authorization\.IConsentConstraintEnforcer')\. Asserts `granted ⊆ requested` for scopes,
resources \(including their nested scopes\) and RFC 9396 `authorization_details`, throwing
when the consent provider returned anything outside the request\.

```csharp
public ConsentConstraintEnforcer(Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailsPolicy authorizationDetailsPolicy);
```
#### Parameters

###### `authorizationDetailsPolicy` [IAuthorizationDetailsPolicy](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailsPolicy 'Abblix\.Oidc\.Server\.Features\.RichAuthorizationRequests\.IAuthorizationDetailsPolicy') {#Abblix.Oidc.Server.Endpoints.Authorization.ConsentConstraintEnforcer.ConsentConstraintEnforcer(Abblix.Oidc.Server.Features.RichAuthorizationRequests.IAuthorizationDetailsPolicy).authorizationDetailsPolicy}

Re\-runs granted `authorization_details` through the
            per\-type validators and per\-client allowlist; the per\-type validator owns the "is B a narrowing
            of A" decision for intra\-entry content \(RFC 9396 §6\.1 has no universal comparator\)\.
### Methods

## ConsentConstraintEnforcer\.EnforceAsync\(ValidAuthorizationRequest, ConsentDefinition, CancellationToken\) Method {#Abblix.Oidc.Server.Endpoints.Authorization.ConsentConstraintEnforcer.EnforceAsync(Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest,Abblix.Oidc.Server.Features.Consents.ConsentDefinition,System.Threading.CancellationToken)}

Asserts that the granted consent does not exceed the request, and returns the
`authorization_details` as the per\-type validators left them\.

```csharp
public System.Threading.Tasks.Task<System.Text.Json.Nodes.JsonArray?> EnforceAsync(Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest request, Abblix.Oidc.Server.Features.Consents.ConsentDefinition granted, System.Threading.CancellationToken cancellationToken);
```
#### Parameters

###### `request` [ValidAuthorizationRequest](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest 'Abblix\.Oidc\.Server\.Endpoints\.Authorization\.Interfaces\.ValidAuthorizationRequest') {#Abblix.Oidc.Server.Endpoints.Authorization.ConsentConstraintEnforcer.EnforceAsync(Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest,Abblix.Oidc.Server.Features.Consents.ConsentDefinition,System.Threading.CancellationToken).request}

The validated authorization request carrying the requested scopes,
            resources and `authorization_details`\.

###### `granted` [ConsentDefinition](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.Consents.ConsentDefinition 'Abblix\.Oidc\.Server\.Features\.Consents\.ConsentDefinition') {#Abblix.Oidc.Server.Endpoints.Authorization.ConsentConstraintEnforcer.EnforceAsync(Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest,Abblix.Oidc.Server.Features.Consents.ConsentDefinition,System.Threading.CancellationToken).granted}

The consent decision produced by [IUserConsentsProvider](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.Consents.IUserConsentsProvider 'Abblix\.Oidc\.Server\.Features\.Consents\.IUserConsentsProvider')\.

###### `cancellationToken` [System\.Threading\.CancellationToken](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken 'System\.Threading\.CancellationToken') {#Abblix.Oidc.Server.Endpoints.Authorization.ConsentConstraintEnforcer.EnforceAsync(Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest,Abblix.Oidc.Server.Features.Consents.ConsentDefinition,System.Threading.CancellationToken).cancellationToken}

Cancellation token\.

Implements [EnforceAsync\(ValidAuthorizationRequest, ConsentDefinition, CancellationToken\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Endpoints.Authorization.IConsentConstraintEnforcer#Abblix.Oidc.Server.Endpoints.Authorization.IConsentConstraintEnforcer.EnforceAsync(Abblix.Oidc.Server.Endpoints.Authorization.Interfaces.ValidAuthorizationRequest,Abblix.Oidc.Server.Features.Consents.ConsentDefinition,System.Threading.CancellationToken) 'Abblix\.Oidc\.Server\.Endpoints\.Authorization\.IConsentConstraintEnforcer\.EnforceAsync\(Abblix\.Oidc\.Server\.Endpoints\.Authorization\.Interfaces\.ValidAuthorizationRequest, Abblix\.Oidc\.Server\.Features\.Consents\.ConsentDefinition, System\.Threading\.CancellationToken\)')

#### Returns
[System\.Threading\.Tasks\.Task&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[System\.Text\.Json\.Nodes\.JsonArray](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.nodes.jsonarray 'System\.Text\.Json\.Nodes\.JsonArray')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
The granted `authorization_details` as re\-validated, or `null` when the
            consent decision carried none\. A re\-validation that returns nothing leaves the granted set
            standing, so `null` never means "the validators emptied it"\.

#### Exceptions

[System\.InvalidOperationException](https://learn.microsoft.com/en-us/dotnet/api/system.invalidoperationexception 'System\.InvalidOperationException')  
Thrown when the granted set contains a scope,
            resource, resource scope or `authorization_details` entry absent from \- or broader than \-
            the request; and equally when the array leaving the per\-type re\-validation does, since that is
            the one the grant is built from\. Also thrown when an entry cannot be read as a JSON object,
            when one carries no `type`, and when the re\-validation answers with an empty set, which
            says every entry was removed and leaves nothing to issue a grant for\.

### Remarks
What this bounds is TYPES and shapes, and deliberately not cardinality: a per\-type validator
answering with several entries of a type the user did grant is accepted, because RFC 9396 offers
no comparator that would say whether three entries of a type narrow one\. A deployment that needs
that bound sets it inside the per\-type validator, which is the only place that knows what a
second entry of its own type means\.
