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

## IUserCodeVerificationService Interface

Defines the contract for a service that handles user code verification
in the Device Authorization Grant flow \(RFC 8628\)\.

```csharp
public interface IUserCodeVerificationService
```

Derived  
↳ [UserCodeVerificationService](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.DeviceAuthorization.UserCodeVerificationService 'Abblix\.Oidc\.Server\.Features\.DeviceAuthorization\.UserCodeVerificationService')
### Methods

## IUserCodeVerificationService\.ApproveAsync\(string, AuthorizedGrant\) Method {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.ApproveAsync(string,Abblix.Oidc.Server.Endpoints.Token.Interfaces.AuthorizedGrant)}

Approves the device authorization request, linking the user's authorization to the pending device\.

```csharp
System.Threading.Tasks.Task<bool> ApproveAsync(string userCode, Abblix.Oidc.Server.Endpoints.Token.Interfaces.AuthorizedGrant authorizedGrant);
```
#### Parameters

###### `userCode` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.ApproveAsync(string,Abblix.Oidc.Server.Endpoints.Token.Interfaces.AuthorizedGrant).userCode}

The user\-entered verification code\.

###### `authorizedGrant` [AuthorizedGrant](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Endpoints.Token.Interfaces.AuthorizedGrant 'Abblix\.Oidc\.Server\.Endpoints\.Token\.Interfaces\.AuthorizedGrant') {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.ApproveAsync(string,Abblix.Oidc.Server.Endpoints.Token.Interfaces.AuthorizedGrant).authorizedGrant}

The authorized grant containing the user's authentication session and
            context\. Its `authorization_details` are what the device is granted: the library adds none, and
            refuses an approval carrying a type the request never asked for\. Its scopes and resources are a
            starting point rather than the final word \- the token endpoint narrows them against the token
            request \(RFC 8707 section 2\.2\) and adds the certificate and proof\-key confirmations\.

#### 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\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
True when this call is the one that recorded the approval\. False otherwise, and otherwise is
wider than a bad code: the stored record is re\-read and must still be pending, so a denial or
another approval landing first answers false too, as does a request whose lifetime ran out and
one whose grant carries a type the request never asked for\. The decision is not applied in any
of those cases, and nothing about the record changes\.

A true is not a guarantee that nothing landed in between. The re-read and the write are two
store calls, and the store exposes no conditional write, so two concurrent approvals can each
be told true and the later write wins. That window is one store round trip wide.

### Remarks
`authorization_details` are the host's to carry\. The requested entries arrive on
            [ValidUserCode](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.DeviceAuthorization.ValidUserCode 'Abblix\.Oidc\.Server\.Features\.DeviceAuthorization\.ValidUserCode'), and the decision the user made about them belongs on this grant's
            `AuthorizationContext` \- narrowed, enriched or dropped, as the verification page decided\. The
            library does not copy them across, because only that page knows what it displayed, and granting a
            payment nobody was shown is worse than granting none\.
            

Approving with entries on the record and none on the grant is therefore allowed and logged at
warning level. RFC 9396 section 7 is satisfied either way, since its MUST is to return what the
resource owner GRANTED and nothing granted is nothing to return. What matters here is section 9 of
that document: it makes the details reaching the resource server the point of having them, and a
token carrying none leaves it nothing to enforce, which is worth seeing in a log rather than
discovering at the resource
server.

The opposite direction is refused rather than logged. A grant carrying a type the device
authorization request never asked for gives the device authority nobody requested, so the
approval answers `false` and the request stays pending.

## IUserCodeVerificationService\.DenyAsync\(string\) Method {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.DenyAsync(string)}

Denies the device authorization request\.

```csharp
System.Threading.Tasks.Task<bool> DenyAsync(string userCode);
```
#### Parameters

###### `userCode` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.DenyAsync(string).userCode}

The user\-entered verification code\.

#### 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\.Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean 'System\.Boolean')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
True when this call is the one that recorded the denial\. False otherwise, and otherwise is wider
than a bad code: the stored record is re\-read and must still be pending, so a decision that
landed first answers false, as does a request whose lifetime ran out\. Nothing about the record changes in those cases, and a true
carries the same narrowed\-not\-closed window [ApproveAsync\(string, AuthorizedGrant\)](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.ApproveAsync(string,Abblix.Oidc.Server.Endpoints.Token.Interfaces.AuthorizedGrant) 'Abblix\.Oidc\.Server\.Features\.DeviceAuthorization\.Interfaces\.IUserCodeVerificationService\.ApproveAsync\(string, Abblix\.Oidc\.Server\.Endpoints\.Token\.Interfaces\.AuthorizedGrant\)') describes\.

## IUserCodeVerificationService\.VerifyAsync\(string\) Method {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.VerifyAsync(string)}

Verifies a user code and returns the associated device authorization request details\.

```csharp
System.Threading.Tasks.Task<Abblix.Oidc.Server.Features.DeviceAuthorization.UserCodeVerificationResult> VerifyAsync(string userCode);
```
#### Parameters

###### `userCode` [System\.String](https://learn.microsoft.com/en-us/dotnet/api/system.string 'System\.String') {#Abblix.Oidc.Server.Features.DeviceAuthorization.Interfaces.IUserCodeVerificationService.VerifyAsync(string).userCode}

The user\-entered verification code\.

#### Returns
[System\.Threading\.Tasks\.Task&lt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')[UserCodeVerificationResult](https://www.abblix.com/docs/api/abblix-oidc-server/Abblix.Oidc.Server.Features.DeviceAuthorization.UserCodeVerificationResult 'Abblix\.Oidc\.Server\.Features\.DeviceAuthorization\.UserCodeVerificationResult')[&gt;](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1 'System\.Threading\.Tasks\.Task\`1')  
A task that returns the verification result containing request details if valid,
or an appropriate error if the code is invalid, expired, or already used\.
