# WebAuthn Class

The WebAuthn class provides a simple way to implement a WebAuthn Relying Party server in your web application.

## Syntax

```text
ipworksauth.WebAuthn
```

## Remarks

The WebAuthn class provides a simple way to implement a WebAuthn Relying Party server, enabling passwordless authentication in your web application.

A typical Relying Party consists of two entities: the server-side logic and the front-end script. The WebAuthn class implements the server-side logic. The implementation and communication between these two key entities is up to the application. For a simple example, please refer to the demo in the installation directory.

## Setup

### Credential Storage

Before utilizing the class the application should implement some credential repository, storage, or database used to store and retrieve user credentials. The exact implementation of this storage is up to the application. For example, in the included demo, user credential information is stored in a text file on disk. Other implementations could store credentials in memory, a database, etc.

For more information on when to store and retrieve user credentials, and what information is necessary, please refer to the registration and authentication sections below.

### Configuring the Relying Party Server

A Relying Party Server has multiple properties that serve as identifiers to WebAuthn clients. These can be configured in the WebAuthn class by using the following properties:

- [Origin](#origin-property-webauthn-class)
- [RelyingPartyId](#relyingpartyid-property-webauthn-class)
- [RelyingPartyName](#relyingpartyname-property-webauthn-class)

The [Origin](#origin-property-webauthn-class) is a **required** property and specifies the full web origin, including the protocol (http or https) and domain, of the Relying Party. For example, this property may be set to *https://login.example.com:7112*. This property, along with [RelyingPartyId](#relyingpartyid-property-webauthn-class), ensures the application's security by restricting requests to valid origins and domains, preventing unauthorized entities from attempting to use credentials.

The [RelyingPartyId](#relyingpartyid-property-webauthn-class) is a valid domain string used to identify the Relying Party during registration or authentication. By default, this value is empty, and will be calculated by parsing the default effective domain of the specified [Origin](#origin-property-webauthn-class). Using the previous example, this would mean *login.example.com* would be used as the [RelyingPartyId](#relyingpartyid-property-webauthn-class).

The [RelyingPartyId](#relyingpartyid-property-webauthn-class) can be manually specified, though it should be ensured that a valid effective domain is defined for the given [Origin](#origin-property-webauthn-class). Using the previous example, *example.com* would suffice, however, *m.login.example.com* would be an invalid identifier.

The [RelyingPartyName](#relyingpartyname-property-webauthn-class) is a user-friendly identifier for the class, intended only for display. For example, this could be set to a company name, such as *ACME Corporation*.

**Related Origins**

If manually specified, the [RelyingPartyId](#relyingpartyid-property-webauthn-class) must be equal to an effective domain of the [Origin](#origin-property-webauthn-class). However, singular domains can prove difficult for deployments in larger environments, where multiple country-specific domains are in use.

As such, the [Origin](#origin-property-webauthn-class) property may be used to specify a comma-separated list of possible origins, for example, *https://example.com:7112,https://example.co.uk:7112*. Implementations can allow clients to create and use a credential across this set of origins.

In this case, implementations **must** manually specify a [RelyingPartyId](#relyingpartyid-property-webauthn-class) to use across all operations from related origins. Additionally, a JSON document **must** be hosted at the webauthn well-known URL for the [RelyingPartyId](#relyingpartyid-property-webauthn-class) (e.g., hosted at https://RelyingPartyId/.well-known/webauthn) as described [here](https://w3c.github.io/webauthn/#sctn-related-origins). This document should contain all origins specified in [Origin](#origin-property-webauthn-class).

Please see below for a simple example of configuring the mentioned properties. Note that at the very least, [Origin](#origin-property-webauthn-class) must be set for each step of the registration and authentication processes below.

```csharp
WebAuthn server = new WebAuthn();

// Automatically set RelyingPartyId to default effective domain
server.Origin = "https://login.example.com:7112";
server.RelyingPartyName = "Example Name";

Console.WriteLine(server.RelyingPartyId); // Prints "login.example.com"

// Manually set RelyingPartyId to a different effective domain
server.Origin = "https://login.example.com:7112";
server.RelyingPartyId = "example.com";
server.RelyingPartyName = "Example Name";

// Specify related origins
server.Origin = "https://login.example.com:7112,https://login.example.co.uk:7112";
server.RelyingPartyId = "example.com";
server.RelyingPArtyName = "Example Name";
```

## Registration

### Creating Registration Options

To create a new user credential, a user must first initiate the registration process. Typically, the user initiates a request to the front-end script, which should then communicate with the class to start this process.

During registration, the class is first required to build options for creating, or registering, a new user credential by calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class). After receiving a request from a front-end, several relevant properties should be set before building these options.

In addition to setting the Relying Party properties, as mentioned in the previous section, the only other **required** property to set is the [UserName](#username-property-webauthn-class). The [UserName](#username-property-webauthn-class) property should be set to the user-friendly identifier for the user account attempting registration. Typically, the [UserName](#username-property-webauthn-class) is provided by the client in the front-end request. The client may also provide the [UserDisplayName](#userdisplayname-property-webauthn-class), specifying a name associated with the user account intended only for display.

The [UserId](#userid-property-webauthn-class) property may be set to some unique identifier for the relevant [UserName](#username-property-webauthn-class). By default, the [UserId](#userid-property-webauthn-class) is empty, and will be calculated by the class as the SHA256 hash of the provided [UserName](#username-property-webauthn-class). If manually specified, implementations should ensure that this identifier is unique to the user, and available in future operations related to this user.

Lastly, it may be that the specified [UserName](#username-property-webauthn-class) has existing credentials previously obtained from various authenticators. Before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class), implementations should query their existing credential database for credentials associated with the specified [UserName](#username-property-webauthn-class). Once identified, the [UserCredentials](#usercredentials-property-webauthn-class) collection should be populated by calling [AddUserCredential](#addusercredential-method-webauthn-class) for each credential. Doing so will ensure that a new credential is not created on an authenticator containing a credential mapped to this [UserName](#username-property-webauthn-class). While not explicitly required, this step should be performed.

The following properties may also be set or modified for additional configuration of the produced registration options:

- [AttestationType](#attestationtype-property-webauthn-class)
- [AuthenticatorAttachment](#authenticatorattachment-property-webauthn-class)
- [DiscoverableCredentials](#discoverablecredentials-property-webauthn-class)
- [Extensions](#extensions-property-webauthn-class)
- [PublicKeyAlgorithms](#publickeyalgorithms-property-webauthn-class)
- [Timeout](#timeout-property-webauthn-class)
- [UserVerification](#userverification-property-webauthn-class)

Once the class is configured, [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) should be called, producing a JSON string of the relevant options that should be returned to the client. Implementations should store the created options somewhere for use during verification (see below). For example, these options could be stored in the HTTP session context, which should persist during registration.

The client should pass these options to the JavaScript function *navigator.credentials.create()*. After doing so, the client will then interact with the authenticator. For example, the client may enter a PIN or touch a security key. Assuming this is successful, *navigator.credentials.create()* will return the authenticator response, which should then be returned to the class.

Please see below for an example of configuring the class in this case, and storing the options in the HTTP context:

```csharp
server.UserName = "test";
server.UserDisplayName = "Test User";

// Some List of WACredential type, search by UserName
List<WACredential> existingCredentials = QueryCredentialsByUser(server.UserName);

for (int i = 0; i < existingCredentials.Count; i++) {
  server.AddUserCredential(existingCredentials[i].IdB, existingCredentials[i].PublicKey, existingCredentials[i].SignCount, existingCredentials[i].SignAlgorithm)
}

// JSON options string that should be returned to the client and passed to navigator.credentials.create()
string ret = server.CreateRegistrationRequest();

// Store the options in the same context for later use during registration.
context.Session.SetString("registrationOptions", ret);
```

### Verifying the Registration Response

Assuming a response has been received from the authenticator, to complete registration, the client must provide this response to the class. To verify the authenticator response, [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) should be called, taking the options previously generated with [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) and the recently received response as parameters.

After calling [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class), the [RegistrationInfo](#registrationinfo-event-webauthn-class) event will fire, providing the Id of the recently created credential. During this event, implementations should search for the provided credential Id in their database. Credential Ids must be unique, i.e., no existing credential in the database may have the provided credential Id. If the provided credential Id exists for **any** user, verification should fail, and the *Cancel* parameter of [RegistrationInfo](#registrationinfo-event-webauthn-class) should be set to true to do so.

Assuming the credential Id does not exist for any other user and the additional verification performed by the class succeeds, [RegistrationComplete](#registrationcomplete-event-webauthn-class) will fire. This event will provide various information about the newly created credential record. During this event, implementations should save this information to their existing credential database for use during future registration or authentication ceremonies. Specifically, implementations should save the following values associated with the credential record.

1. The current [UserName](#username-property-webauthn-class) associated with the credential.
2. If manually specified, the associated [UserId](#userid-property-webauthn-class).
3. The *CredentialId* parameter of [RegistrationComplete](#registrationcomplete-event-webauthn-class).
4. The *PublicKey* parameter of [RegistrationComplete](#registrationcomplete-event-webauthn-class).
5. The *SignCount* parameter of [RegistrationComplete](#registrationcomplete-event-webauthn-class).
6. The *Algorithm* parameter of [RegistrationComplete](#registrationcomplete-event-webauthn-class).

Additionally, implementations **may** wish to store the [BackupEligible](#BackupEligible), [BackupState](#BackupState), and [UvInitialized](#UvInitialized) configs as well.

Once the relevant credential information is saved, registration is officially complete, and the registered credential may be used in future authentication ceremonies.

Please see below for an example of the verification process:

```csharp
server.OnRegistrationInfo += (o, e) => {
  // Some List of WACredential type, search by Credential Id
  existingCredentials = QueryCredentialsById(e.CredentialId);

  if (existingCredentials.Count != 0) {
    // Registration should fail since CredentialId exists
    e.Cancel = true;
  }
};

server.OnRegistrationComplete += (o, e) => {
  // Save credential info for authentication
  SaveCredential(server.UserName, e.CredentialIdB, e.PublicKey, e.SignCount, e.Algorithm);
};

string response = StreamReader(context.Request.Body).ReadToEnd();
string cachedOptions = context.Session.GetString("registrationOptions") ?? String.Empty;

server.VerifyRegistrationResponse(response, options);

Console.WriteLine("Registration Successful.");
```

## Authentication

### Creating Authentication Options

To log in using an existing credential, a user must first initiate the authentication process. Typically, the user initiates a request to the front end which should communicate directly with the class to start this process.

During authentication, the class is first required to build options for logging in using an existing user credential by calling [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class). After receiving a request from a front-end, several relevant properties should be set before building these options.

In addition to setting the Relying Party properties, as mentioned in the first section, there are no required properties that must be set before calling [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class).

Typically, the user attempting to log in will provide the username associated with their account, however, this is not a requirement. If the username is provided, implementations should query their existing credential database for any credentials associated with this username. Once identified, the [UserCredentials](#usercredentials-property-webauthn-class) collection should be populated by calling [AddUserCredential](#addusercredential-method-webauthn-class) for each user credential. When sending the options to the client in a later step, the authenticator will then allow the client to select from these credentials during authentication. Note that the [UserName](#username-property-webauthn-class) property should not be specified in this case, as it is not included in the options.

If the client does not specify a username, implementations should leave the [UserCredentials](#usercredentials-property-webauthn-class) collection empty. When sending the options to the client in a later step, the authenticator will then allow the client to utilize any discoverable credentials that were previously created. Discoverable credentials are made available to the client in this specific case, and the client may choose any of the existing discoverable credentials as presented by the authenticator. A discoverable credential can be created during registration. The class can indicate its preference regarding whether a discoverable credential is created using the [DiscoverableCredentials](#discoverablecredentials-property-webauthn-class) property during this step. If no discoverable credentials exist, this will result in an error.

The following properties may also be set or modified for additional configuration of the produced login options:

- [Extensions](#extensions-property-webauthn-class)
- [Timeout](#timeout-property-webauthn-class)

Once the class is configured, [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class) should be called, producing a JSON string of the relevant options that should be returned to the client. Implementations should store the created options somewhere for use during verification (see below). For example, these options could be stored in the HTTP session context, which should persist during authentication.

The client should pass these options to the JavaScript function *navigator.credentials.get()*. After doing so, the client will then interact with the authenticator. For example, the client may enter a PIN or touch a security key. Assuming this is successful, *navigator.credentials.get()* will return the authenticator response, which should then be returned to the class.

Please see below for an example of configuring the class in this case, and storing the options in the HTTP context:

```csharp
string userName = "test"; // If provided, optional
List<existingCredentials> = QueryCredentialsByUser(userName);

for (int i = 0; i < existingCredentials.Count; i++) {
  server.AddUserCredential(existingCredentials[i].IdB, existingCredentials[i].PublicKey, existingCredentials[i].SignCount, existingCredentials[i].SignAlgorithm)
}

// JSON options string that should be returned to the client and passed to navigator.credentials.create()
string ret = server.CreateAuthenticationRequest();

// Store the options in the same context for later use during login.
context.Session.SetString("loginOptions", ret);
```

### Verifying the Authentication Response

Assuming a response has been received from the authenticator, to complete the login process, the client must provide this response to the class. To verify the authenticator response, [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class) should be called, taking the recently received response, and the options previously generated with [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class) (stored in the HTTP context).

After calling [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class), the [AuthenticationInfo](#authenticationinfo-event-webauthn-class) event will fire, providing the Id of the recently created credential. During this event, implementations should search for the provided credential Id in their database. Since a user is attempting to use an existing credential, it is assumed this credential exists in the database. If the provided credential Id does not exist, the *Cancel* parameter of [AuthenticationInfo](#authenticationinfo-event-webauthn-class) should be set to true, and verification should fail.

Assuming the credential exists in the database, the following properties and event parameters should be set during [AuthenticationInfo](#authenticationinfo-event-webauthn-class):

- The current [UserName](#username-property-webauthn-class) associated with the credential.
- If manually specified, the associated [UserId](#userid-property-webauthn-class).
- The *PublicKey* parameter of [AuthenticationInfo](#authenticationinfo-event-webauthn-class).
- The *SignCount* parameter of [AuthenticationInfo](#authenticationinfo-event-webauthn-class).
- The *Algorithm* parameter of [AuthenticationInfo](#authenticationinfo-event-webauthn-class).

Assuming this information is correct, the class will continue the verification process accordingly, and [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) will fire. This event will provide necessary information regarding any updates to the existing credential. During this event, implementations should update the credential in their database for future use. Specifically, implementations should update the signature counter associated with the credential record by utilizing the *SignCount* parameter of [AuthenticationComplete](#authenticationcomplete-event-webauthn-class).

Implementations **may** wish to query the values of the [BackupState](#BackupState) and [UvInitialized](#UvInitialized) configs to update the stored credential record accordingly.

Once the relevant credential information is updated, authentication is complete.

Please see below for an example of the verification process:

```csharp
server.OnAuthenticationInfo += (o, e) => {
  // Search for single Credential Id
  existingCredential = QueryCredentialById(e.CredentialId);
  string user = QueryUserById(e.CredentialId);

  if (existingCredential == null) {
    // Authentication should fail since CredentialId does not exist
    e.Cancel = true;
  }

  server.UserName = user;
  e.PublicKey = existingCredential.PublicKey;
  e.SignCount = existingCredential.SignCount;
  e.Algorithm = existingCredential.SignAlgorithm;
};

server.OnAuthenticationComplete += (o, e) => {
  // Update credential info
  SaveCredential(e.CredentialIdB, e.SignCount);
};

string response = new StreamReader(context.Request.Body).ReadToEnd();
string cachedOptions = context.Session.GetString("loginOptions") ?? String.Empty;

server.VerifyAuthenticationResponse(response, options);

Console.WriteLine("Authentication Successful.");
```

## Property List

*The following is the full list of the properties of the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [AttestationType](#attestationtype-property-webauthn-class) | Specifies the preference regarding attestation conveyance during registration. |
| [AuthenticatorAttachment](#authenticatorattachment-property-webauthn-class) | Specifies the preference regarding authenticator attachment modality during registration. |
| [DiscoverableCredentials](#discoverablecredentials-property-webauthn-class) | Specifies whether the Relying Party wishes to create a client-side discoverable credential during registration. |
| [Extensions](#extensions-property-webauthn-class) | Specifies extensions that will either be sent to the client, or have been sent to the class. |
| [Origin](#origin-property-webauthn-class) | Specifies the full web origin, including the protocol (http or https) and domain, of the class (WebAuthn Relying Party). |
| [PublicKeyAlgorithms](#publickeyalgorithms-property-webauthn-class) | Specifies an ordered, comma-separated list of acceptable algorithms for the public key during registration. |
| [RelyingPartyId](#relyingpartyid-property-webauthn-class) | Specifies the unique identifier of the Relying Party. |
| [RelyingPartyName](#relyingpartyname-property-webauthn-class) | Specifies a user-friendly name for the WebAuthn Relying Party. |
| [Timeout](#timeout-property-webauthn-class) | Specifies a time, in seconds, that the Relying Party is willing to wait for the operation to complete. |
| [UserCredentials](#usercredentials-property-webauthn-class) | Specifies existing credentials for a user account. |
| [UserDisplayName](#userdisplayname-property-webauthn-class) | Specifies a user-friendly name for the associated user account intended only for display. |
| [UserId](#userid-property-webauthn-class) | Specifies the user Id, or user handle, for the associated user account. |
| [UserName](#username-property-webauthn-class) | Specifies a user-friendly name for the associated user account. |
| [UserVerification](#userverification-property-webauthn-class) | Specifies the Relying Party's requirements regarding user verification during registration. |

## Method List

*The following is the full list of the methods of the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [AddExtension](#addextension-method-webauthn-class) | Used to add an extension to include when building the options for registration or authentication. |
| [AddUserCredential](#addusercredential-method-webauthn-class) | Used to add a user credential to the UserCredentials collection. |
| [Config](#config-method-webauthn-class) | Sets or retrieves a configuration setting. |
| [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class) | Used to build the request options for a user attempting to login, or authenticate, using an existing credential. |
| [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) | Used to build the request options for a user attempting to register a new credential. |
| [Reset](#reset-method-webauthn-class) | Resets the class properties. |
| [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class) | Used to log in, or authenticate, using an existing credential. |
| [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) | Used to register a new credential. |

## Event List

*The following is the full list of the events fired by the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) | Fired when a user successfully logs in. |
| [AuthenticationInfo](#authenticationinfo-event-webauthn-class) | Fired when the class requests additional information regarding the existing credential. |
| [Error](#error-event-webauthn-class) | Fired when information is available about errors during data delivery. |
| [Extension](#extension-event-webauthn-class) | Fired when an extension is found while verifying an authenticator response. |
| [Log](#log-event-webauthn-class) | Fired once for each log message. |
| [RegistrationComplete](#registrationcomplete-event-webauthn-class) | Fired when a user is successfully registered. |
| [RegistrationInfo](#registrationinfo-event-webauthn-class) | Fired when the class requests additional information regarding the new credential. |

## Config Settings

*The following is a list of config settings for the class with short descriptions. Click on the links for further details.*

|  |  |
| --- | --- |
| [BackupEligible](#BackupEligible) | Indicates or specifies the backup eligibility of a credential. |
| [BackupState](#BackupState) | Indicates the backup state of a credential. |
| [Hints](#Hints) | Specifies any hints to communicate to the user-agent about how a request may be completed. |
| [ServerChallenge](#ServerChallenge) | Specifies the cryptographic challenge associated with the current options, as specified by the class. |
| [UvInitialized](#UvInitialized) | Indicates whether user verification has been performed for a new or existing credential. |
| [BuildInfo](#BuildInfo) | Information about the product's build. |
| [GUIAvailable](#GUIAvailable) | Whether or not a message loop is available for processing events. |
| [LicenseInfo](#LicenseInfo) | Information about the current license. |
| [MaskSensitiveData](#MaskSensitiveData) | Whether sensitive data is masked in log messages. |
| [UseDaemonThreads](#UseDaemonThreads) | Whether threads created by the class are daemon threads. |
| [UseFIPSCompliantAPI](#UseFIPSCompliantAPI) | Tells the class whether or not to use FIPS certified APIs. |
| [UseInternalSecurityAPI](#UseInternalSecurityAPI) | Whether or not to use the system security libraries or an internal implementation. |
| [UseVirtualThreads](#UseVirtualThreads) | Whether threads created by the class use virtual threads instead of platform threads. |

# AttestationType Property ([WebAuthn](#webauthn-class) Class)

Specifies the preference regarding attestation conveyance during registration.

## Syntax

```text
public int getAttestationType();
public void setAttestationType(int attestationType);

Enumerated values:
  public final static int atNone = 0;
  public final static int atIndirect = 1;
  public final static int atDirect = 2;
  public final static int atEnterprise = 3;
```

## Default Value

0

## Remarks

This property specifies the preference regarding attestation conveyance during registration. This value may be set prior to calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class). Possible values include:

|  |  |
| --- | --- |
| 0 (atNone - default) | Indicates the Relying Party is not interested in an attestation. |
| 1 (atIndirect) | Indicates the Relying Party wants to receive a verifiable attestation, but allows the client to decide how to obtain such an attestation statement. |
| 2 (atDirect) | Indicates the Relying Party wants to receive the attestation statement as generated by the authenticator. |
| 3 (atEnterprise) | Indicates the Relying Party wants to receive an attestation statement that may include uniquely identifying information. |

# AuthenticatorAttachment Property ([WebAuthn](#webauthn-class) Class)

Specifies the preference regarding authenticator attachment modality during registration.

## Syntax

```text
public int getAuthenticatorAttachment();
public void setAuthenticatorAttachment(int authenticatorAttachment);

Enumerated values:
  public final static int atAny = 0;
  public final static int atPlatform = 1;
  public final static int atCrossPlatform = 2;
```

## Default Value

0

## Remarks

This property specifies the preference regarding authenticator attachment modality. This value may be set prior to calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class). Possible values include:

|  |  |
| --- | --- |
| 0 (atAny - default) | Indicates the Relying Party does not have a preference between platform and cross-platform authenticators. |
| 1 (atPlatform) | Indicates the Relying Party prefers the use of a platform authenticator, i.e., a non-removable authenticator. |
| 2 (atCrossPlatform) | Indicates the Relying Party prefers the use of a cross-platform attachment, i.e., a roaming authenticator. |

Note that this value may not affect which types of authenticators (platform or cross-platform) are presented to the client, as it only indicates server-side preference.

This property is not available at design time.

# DiscoverableCredentials Property ([WebAuthn](#webauthn-class) Class)

Specifies whether the Relying Party wishes to create a client-side discoverable credential during registration.

## Syntax

```text
public int getDiscoverableCredentials();
public void setDiscoverableCredentials(int discoverableCredentials);

Enumerated values:
  public final static int dcUnspecified = 0;
  public final static int dcDiscouraged = 1;
  public final static int dcPreferred = 2;
  public final static int dcRequired = 3;
```

## Default Value

0

## Remarks

This property specifies whether the Relying Party wishes to create a client-side discoverable credential during registration. This value may be set prior to calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class). Possible values include:

|  |  |
| --- | --- |
| 0 (dcUnspecified - default) | The option will not be specified in the returned value of [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class). |
| 1 (dcDiscouraged) | The Relying Party prefers creating a server-side credential, but will accept a client-side discoverable credential. |
| 2 (dcPreferred) | The Relying Party strongly prefers creating a client-side discoverable credential, but will accept a server-side credential. |
| 3 (dcRequired) | The Relying Party requires a client-side discoverable credential. |

As some background, a discoverable credential is a credential that is discoverable and usable during authentication ceremonies where the [UserCredentials](#usercredentials-property-webauthn-class) is empty, i.e., when no existing credential Ids are specified. In this case, the Relying Party does not necessarily need to first identify the user. On the client-side, the user will be able to select some appropriate credential to log in with.

Assuming the authentication on the client-side is successful, the authenticator should return a response to the application, which will contain the relevant credential Id used to log in. The associated credential Id will be provided in [AuthenticationInfo](#authenticationinfo-event-webauthn-class), and assuming the credential exists, relevant credential information should be provided.

This property is not available at design time.

# Extensions Property ([WebAuthn](#webauthn-class) Class)

Specifies extensions that will either be sent to the client, or have been sent to the class.

## Syntax

```text
public WAExtensionList getExtensions();
```

## Remarks

This property specifies extensions utilized by the class in two different cases.

In the first case, this property will be populated using [AddExtension](#addextension-method-webauthn-class), which should be called to send extensions to the client prior to [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) and [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class).

In the second case, this property may be populated after parsing an authenticator response with [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) or [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class). Typically, the parsed extensions will be responses to any extensions sent during the first case, and implementations can view the result either in [Extension](#extension-event-webauthn-class), or [RegistrationInfo](#registrationinfo-event-webauthn-class) and [AuthenticationInfo](#authenticationinfo-event-webauthn-class).

In [RegistrationInfo](#registrationinfo-event-webauthn-class) and [AuthenticationInfo](#authenticationinfo-event-webauthn-class) implementations **may** perform validation of the extensions present (or missing) from this collection. While implementations may verify responses to all previously sent extensions were received in the response, implementations **must** be able to handle such situations where unsolicited extensions were received, or certain extensions were ignored. Please see [RegistrationInfo](#registrationinfo-event-webauthn-class) and [AuthenticationInfo](#authenticationinfo-event-webauthn-class) for additional details.

This property is read-only and not available at design time.

 Please refer to the [WAExtension](#waextension-type) type for a complete list of fields.

# Origin Property ([WebAuthn](#webauthn-class) Class)

Specifies the full web origin, including the protocol (http or https) and domain, of the class (WebAuthn Relying Party).

## Syntax

```text
public String getOrigin();
public void setOrigin(String origin);
```

## Default Value

""

## Remarks

This property specifies the full web origin, including the protocol (http or https) and domain, of the class (WebAuthn Relying Party). The origin must be specified before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class), [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class), [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), and [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class).

This property ensures the security of the application by restricting requests to valid origins, preventing unauthorized entities from attempting to use credentials. For example, setting the Origin property to *https://login.example.com:7112* limits requests to that specific domain.

By default, after setting this property, the [RelyingPartyId](#relyingpartyid-property-webauthn-class) will be set to the default effective domain of the origin. In the above example, [RelyingPartyId](#relyingpartyid-property-webauthn-class) would be set to *login.example.com*.

The [RelyingPartyId](#relyingpartyid-property-webauthn-class) can be manually specified, though it should be ensured that a valid effective domain is specified for the given Origin. Using the previous example, *example.com* would suffice, however, *m.login.example.com* would be an invalid identifier.

**Related Origins**

If manually specified, the [RelyingPartyId](#relyingpartyid-property-webauthn-class) must be equal to an effective domain of the Origin. However, singular domains can prove difficult for deployments in larger environments, where multiple country-specific domains are in use.

As such, the Origin property may be used to specify a comma-separated list of possible origins, for example, *https://example.com:7112,https://example.co.uk:7112*. Implementations can allow clients to create and use a credential across this set of origins.

In this case, implementations **must** manually specify a [RelyingPartyId](#relyingpartyid-property-webauthn-class) to use across all operations from related origins. Additionally, a JSON document **must** be hosted at the webauthn well-known URL for the [RelyingPartyId](#relyingpartyid-property-webauthn-class) (e.g., hosted at https://RelyingPartyId/.well-known/webauthn) as described [here](https://w3c.github.io/webauthn/#sctn-related-origins). This document should contain all origins specified in Origin.

# PublicKeyAlgorithms Property ([WebAuthn](#webauthn-class) Class)

Specifies an ordered, comma-separated list of acceptable algorithms for the public key during registration.

## Syntax

```text
public String getPublicKeyAlgorithms();
public void setPublicKeyAlgorithms(String publicKeyAlgorithms);
```

## Default Value

"ES256,RS256"

## Remarks

This property specifies an ordered, comma-separated list of acceptable algorithms for the public key during registration. By default, this value is *ES256,RS256*, and must be specified before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class).

Though those elements are sorted by preference (the first element being the most preferred), it is up to the client to choose among those elements for building the credential.

Possible values to include in this property are:

- ES256 (default)
- RS256 (default)
- ES384
- ES512
- EdDSA
- PS256
- PS384
- PS512
- RS1

The selected algorithm will be made available in [RegistrationComplete](#registrationcomplete-event-webauthn-class), after verifying the authenticator response using [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class).

# RelyingPartyId Property ([WebAuthn](#webauthn-class) Class)

Specifies the unique identifier of the Relying Party.

## Syntax

```text
public String getRelyingPartyId();
public void setRelyingPartyId(String relyingPartyId);
```

## Default Value

""

## Remarks

This property specifies the unique identifier of the WebAuthn Relying Party.

A Relying Party identifier is a valid domain string identifying the WebAuthn Relying Party on whose behalf registration or authentication is being performed.

By default, this value is empty, and will be set as the default effective domain of the [Origin](#origin-property-webauthn-class). For example, if the [Origin](#origin-property-webauthn-class) is specified as *https://example.com*, this property will be set to *example.com*.

The RelyingPartyId can be manually specified after setting [Origin](#origin-property-webauthn-class), though it should be ensured that a valid effective domain is specified for the given origin. Using the previous example, *example.com* would suffice, however, *m.login.example.com* would be an invalid identifier.

NOTE: If the [Origin](#origin-property-webauthn-class) is specified as a comma-separated list of valid origins, this property **must** be manually specified, otherwise, it will remain empty.

# RelyingPartyName Property ([WebAuthn](#webauthn-class) Class)

Specifies a user-friendly name for the WebAuthn Relying Party.

## Syntax

```text
public String getRelyingPartyName();
public void setRelyingPartyName(String relyingPartyName);
```

## Default Value

""

## Remarks

This property specifies a user-friendly identifier for the Relying Party, intended only for display. For example, "ACME Corporation", "Wonderful Widgets, Inc.".

This property may be specified before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class), [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class), [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), and [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class).

# Timeout Property ([WebAuthn](#webauthn-class) Class)

Specifies a time, in seconds, that the Relying Party is willing to wait for the operation to complete.

## Syntax

```text
public int getTimeout();
public void setTimeout(int timeout);
```

## Default Value

60

## Remarks

This property specifies a time, in seconds, that the Relying Party is willing to wait for the operation to complete. By default, this is set to *60* seconds.

When calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) or [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), this value simply represents a hint for the time the class is willing to wait for the completion of the operation. This property is optional and merely is a hint which may be overridden by the browser.

# UserCredentials Property ([WebAuthn](#webauthn-class) Class)

Specifies existing credentials for a user account.

## Syntax

```text
public WACredentialList getUserCredentials();
```

## Remarks

This property specifies existing credentials for a user account. This collection may be populated using [AddUserCredential](#addusercredential-method-webauthn-class) before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) or [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class).

Before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class), [AddUserCredential](#addusercredential-method-webauthn-class) may be called for each credential that exists for the specified [UserName](#username-property-webauthn-class). This will ensure that the new credential is not created on an authenticator that already contains a credential mapped to the specific [UserName](#username-property-webauthn-class). If a mapped credential for the selected authenticator already exists, this may result in an error.

Before calling [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), if a username is provided by the front-end, [AddUserCredential](#addusercredential-method-webauthn-class) may be called for each existing credential for the identified user account. The [UserName](#username-property-webauthn-class) property should not be specified in this case, as it is not included in the options.

If a username is not provided by the front-end, [AddUserCredential](#addusercredential-method-webauthn-class) should not called, and only discoverable credentials will be utilized for authentication. In this case, the user will select the relevant credential during authentication, unknown to the class initially. After receiving a response from the authenticator and calling [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class), the utilized credential will be present in [AuthenticationInfo](#authenticationinfo-event-webauthn-class).

This property is read-only and not available at design time.

 Please refer to the [WACredential](#wacredential-type) type for a complete list of fields.

# UserDisplayName Property ([WebAuthn](#webauthn-class) Class)

Specifies a user-friendly name for the associated user account intended only for display.

## Syntax

```text
public String getUserDisplayName();
public void setUserDisplayName(String userDisplayName);
```

## Default Value

""

## Remarks

This property specifies a user-friendly name for the associated user account intended only for display.

# UserId Property ([WebAuthn](#webauthn-class) Class)

Specifies the user Id, or user handle, for the associated user account.

## Syntax

```text
public byte[] getUserId();
public void setUserId(byte[] userId);
```

## Default Value

""

## Remarks

This property specifies the user Id, or user handle, for the associated user account. By default, this value will be empty. If left unspecified, the Id will be calculated as the SHA256 hash of the [UserName](#username-property-webauthn-class) property for use during registration and authentication.

If manually specified, this property will be used instead. In this case, it should be ensured that the specified Id is an opaque byte sequence with a maximum size of 64 bytes.

Note that this property is not meant to be displayed to the user.

# UserName Property ([WebAuthn](#webauthn-class) Class)

Specifies a user-friendly name for the associated user account.

## Syntax

```text
public String getUserName();
public void setUserName(String userName);
```

## Default Value

""

## Remarks

This property specifies a user-friendly name or identifier for the associated user account. This property must be set prior to calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class).

For example, possible values include: "alexm", "+14255551234", "alex.mueller@example.com", "alex.mueller@example.com (prod-env)".

By default, the [UserId](#userid-property-webauthn-class) will be calculated as the SHA256 hash of this property for use during registration and authentication.

# UserVerification Property ([WebAuthn](#webauthn-class) Class)

Specifies the Relying Party's requirements regarding user verification during registration.

## Syntax

```text
public int getUserVerification();
public void setUserVerification(int userVerification);

Enumerated values:
  public final static int uvRequired = 0;
  public final static int uvPreferred = 1;
  public final static int uvDiscouraged = 2;
```

## Default Value

1

## Remarks

This property specifies whether the Relying Party's requirements regarding user verification during registration. Possible values include:

|  |  |
| --- | --- |
| 0 (uvRequired) | The Relying Party requires user verification during registration or authentication, in that an error should be returned if user verification cannot be performed, or fails. |
| 1 (uvPreferred - default) | The Relying Party prefers user verification during registration or authentication if possible, but will not fail the operation if user verification is not performed. |
| 2 (uvDiscouraged) | The Relying Party discourages user verification during registration or authentication, but will not fail the operation if user verification is performed. |

As some background, an authenticator must support at least one authentication factor. An authenticator that supports one or more additional authentication factors (i.e., 2 or 3 total authentication factors) can support user verification, and is known as a multi-factor capable authenticator. In that regard, an authenticator that is not multi-factor capable is defined as single-factor capable, and do not support user verification. If this property is set to *0* (uvRequired) and the client attempts to utilize a single-factor capable authenticator, registration will fail.

Whether user verification was successful, or even performed, is indicated by the [UvInitialized](#UvInitialized) config, which may be queried during [RegistrationComplete](#registrationcomplete-event-webauthn-class) or [AuthenticationComplete](#authenticationcomplete-event-webauthn-class). This config may be stored or updated during these events for future use.

# AddExtension Method ([WebAuthn](#webauthn-class) Class)

Used to add an extension to include when building the options for registration or authentication.

## Syntax

```text
public void addExtension(String name, String value, int valueType);
```

## Remarks

This method is used to add an extension to include when building the options for registration or authentication (i.e., when calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) and [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), respectively).

The *Name* parameter specifies the name of the extension.

The *Value* parameter specifies the value of the extension.

The *ValueType* parameter specifies the type of the value. Possible values are as follows:

- 0 (Object)
- 1 (Array)
- 2 (String)
- 3 (Number)
- 4 (Bool)
- 5 (Null)
- 6 (Raw)

For example, to include the registered FIDO AppId Extension (appid) when calling [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), you can do the following:

```text
webauthn.AddExtension("appid", "some_legacy_rp_id", 2);
```

Assuming the extensions are supported by the authenticator and client, the extension outputs are reported when verifying the response after calling either [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) or [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class). For each extension, the [Extension](#extension-event-webauthn-class) event will fire with the relevant response parameters and types.

In the above case, the extension output will report either true or false, depending on whether the provided appid was utilized. If true, the [RelyingPartyId](#relyingpartyid-property-webauthn-class) should be updated accordingly to ensure that verification succeeds. For example:

```text
webauthn.OnExtension += (o, e) => {
  // Ensure returned value is a boolean, and true, before updating
  if (e.Name.Equals("appid") && e.ValueType == 4 && bool.Parse(e.Value)) {
    webauthn.RelyingPartyId = "some_legacy_rp_id";
  }
};
```

# AddUserCredential Method ([WebAuthn](#webauthn-class) Class)

Used to add a user credential to the UserCredentials collection.

## Syntax

```text
public void addUserCredential(byte[] credentialId, String publicKey, int signCount, String algorithm);
```

## Remarks

This method is used to add a user credential to the [UserCredentials](#usercredentials-property-webauthn-class) collection, which can be used to hold existing credentials for a specified [UserName](#username-property-webauthn-class) prior to calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) and [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class).

Before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class), this method should be called for each credential that exists for the given [UserName](#username-property-webauthn-class). Included credentials will be specified in the resulting options. This will ensure that the new credential is not created on an authenticator that already contains a credential mapped to the specific [UserName](#username-property-webauthn-class). If a mapped credential for the selected authenticator already exists, this may result in an error.

Before calling [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), if a username is provided by the front-end, AddUserCredential should be called for each existing credential for the identified user account. The [UserName](#username-property-webauthn-class) property should not be specified in this case, as it is not included in the options.

If a username is not provided by the front-end, AddUserCredential should not called, and only discoverable credentials will be utilized for authentication. In this case, the user will select the relevant credential during authentication, unknown to the class initially. After receiving a response from the authenticator and calling [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class), the utilized credential will be present in [AuthenticationInfo](#authenticationinfo-event-webauthn-class).

# Config Method ([WebAuthn](#webauthn-class) Class)

Sets or retrieves a configuration setting.

## Syntax

```text
public String config(String configurationString);
```

## Remarks

Config is a generic method available in every class. It is used to set and retrieve [configuration settings](#config-settings-webauthn-class) for the class.

These settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these *internal properties* is provided through the Config method.

To set a configuration setting named *PROPERTY*, you must call *Config("PROPERTY=VALUE")*, where *VALUE* is the value of the setting expressed as a string. For boolean values, use the strings "True", "False", "0", "1", "Yes", or "No" (case does not matter).

To read (query) the value of a [configuration setting](#config-settings-webauthn-class), you must call *Config("PROPERTY")*. The value will be returned as a string.

# CreateAuthenticationRequest Method ([WebAuthn](#webauthn-class) Class)

Used to build the request options for a user attempting to login, or authenticate, using an existing credential.

## Syntax

```text
public String createAuthenticationRequest();
```

## Remarks

This method is used to build the request options for a user attempting to login, or authenticate, an existing credential, and will return a JSON-formatted string of these options. These options should be returned to the front-end and then passed to *navigator.credentials.get()* after some additional modification.

Before calling this method, [Origin](#origin-property-webauthn-class), [RelyingPartyId](#relyingpartyid-property-webauthn-class), and/or [RelyingPartyName](#relyingpartyname-property-webauthn-class) must be set accordingly.

Additionally, if the user account has been identified (i.e., the user has specified their username), [AddUserCredential](#addusercredential-method-webauthn-class) should be called to populate [UserCredentials](#usercredentials-property-webauthn-class) with existing credentials for the identified user. If the user account has not been specified, [UserCredentials](#usercredentials-property-webauthn-class) may remain empty, implying that only discoverable credentials will be utilized for login.

The following properties may also be set or modified for additional configuration of the produced login options:

- [Extensions](#extensions-property-webauthn-class)
- [Timeout](#timeout-property-webauthn-class)

Please see below for a simple example of this process:

```csharp
string userName = "test"; // If provided, optional
List<existingCredentials> = QueryCredentialsByUser(userName);

for (int i = 0; i < existingCredentials.Count; i++) {
  server.AddUserCredential(existingCredentials[i].IdB, existingCredentials[i].PublicKey, existingCredentials[i].SignCount, existingCredentials[i].SignAlgorithm)
}

// JSON options string that should be returned to the client and passed to navigator.credentials.create()
string ret = server.CreateAuthenticationRequest();

// Store the options in the same context for later use during login.
context.Session.SetString("loginOptions", ret);
```

# CreateRegistrationRequest Method ([WebAuthn](#webauthn-class) Class)

Used to build the request options for a user attempting to register a new credential.

## Syntax

```text
public String createRegistrationRequest();
```

## Remarks

This method is used to build the request options for a user attempting to register, and will return a JSON-formatted string of these options. These options should be returned to the front-end and then passed to *navigator.credentials.create()* after some additional modification.

Before calling this method, [Origin](#origin-property-webauthn-class), [RelyingPartyId](#relyingpartyid-property-webauthn-class), and/or [RelyingPartyName](#relyingpartyname-property-webauthn-class) must be set accordingly.

To identify the user performing registration, the [UserName](#username-property-webauthn-class), [UserDisplayName](#userdisplayname-property-webauthn-class), and [UserId](#userid-property-webauthn-class) should be specified. Additionally, [AddUserCredential](#addusercredential-method-webauthn-class) should be called to populate [UserCredentials](#usercredentials-property-webauthn-class) with existing credentials for the relevant user.

The following properties may also be set or modified for additional configuration of the produced registration options:

- [AttestationType](#attestationtype-property-webauthn-class)
- [AuthenticatorAttachment](#authenticatorattachment-property-webauthn-class)
- [DiscoverableCredentials](#discoverablecredentials-property-webauthn-class)
- [Extensions](#extensions-property-webauthn-class)
- [PublicKeyAlgorithms](#publickeyalgorithms-property-webauthn-class)
- [Timeout](#timeout-property-webauthn-class)
- [UserVerification](#userverification-property-webauthn-class)

Please see below for a simple example of this process:

```csharp
server.UserName = "test";
server.UserDisplayName = "Test User";

// Some List of WACredential type, search by UserName
List<WACredential> existingCredentials = QueryCredentialsByUser(server.UserName);

for (int i = 0; i < existingCredentials.Count; i++) {
  server.AddUserCredential(existingCredentials[i].IdB, existingCredentials[i].PublicKey, existingCredentials[i].SignCount, existingCredentials[i].SignAlgorithm)
}

// JSON options string that should be returned to the client and passed to navigator.credentials.create()
string ret = server.CreateRegistrationRequest();

// Store the options in the same context for later use during registration.
context.Session.SetString("registrationOptions", ret);
```

# Reset Method ([WebAuthn](#webauthn-class) Class)

Resets the class properties.

## Syntax

```text
public void reset();
```

## Remarks

This method resets all message and key properties to their default values.

# VerifyAuthenticationResponse Method ([WebAuthn](#webauthn-class) Class)

Used to log in, or authenticate, using an existing credential.

## Syntax

```text
public void verifyAuthenticationResponse(String response, String options);
```

## Remarks

This method is used to log in, or authenticate, using an existing credential.

Before calling this method, [Origin](#origin-property-webauthn-class), [RelyingPartyId](#relyingpartyid-property-webauthn-class), and/or [RelyingPartyName](#relyingpartyname-property-webauthn-class) must be set accordingly.

The *Response* parameter is used to provide the JSON-formatted authenticator response returned from the front-end call to *navigator.credentials.get()*.

The *Options* parameter is used to provide the options obtained from [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class) during the first step of authentication.

After parsing the *Response* and *Options* parameters, the class will first attempt to verify the *Response*. During verification, [AuthenticationInfo](#authenticationinfo-event-webauthn-class) will fire, requesting additional information regarding the current credential. Within this event, it should be confirmed that the relevant credential used to log in exists. Relevant information about this credential should also be provided to the class. Please see [AuthenticationInfo](#authenticationinfo-event-webauthn-class) for additional information.

Assuming the response is successfully verified, [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) will fire containing updated information about the existing credential, which must be stored for future use. Afterwards, this method will return successfully, indicating the authentication process is complete.

Please see below for a simple example of this process:

```csharp
server.OnAuthenticationInfo += (o, e) => {
  // Search for single Credential Id
  existingCredential = QueryCredentialById(e.CredentialId);
  string user = QueryUserById(e.CredentialId);

  if (existingCredential == null) {
    // Authentication should fail since CredentialId does not exist
    e.Cancel = true;
  }

  server.UserName = user;
  e.PublicKey = existingCredential.PublicKey;
  e.SignCount = existingCredential.SignCount;
  e.Algorithm = existingCredential.SignAlgorithm;
};

server.OnAuthenticationComplete += (o, e) => {
  // Update credential info
  SaveCredential(e.CredentialIdB, e.SignCount);
};

string response = new StreamReader(context.Request.Body).ReadToEnd();
string cachedOptions = context.Session.GetString("loginOptions") ?? String.Empty;

server.VerifyAuthenticationResponse(response, options);

Console.WriteLine("Authentication Successful.");
```

# VerifyRegistrationResponse Method ([WebAuthn](#webauthn-class) Class)

Used to register a new credential.

## Syntax

```text
public void verifyRegistrationResponse(String response, String options);
```

## Remarks

This method is used to register a new credential.

Before calling this method, [Origin](#origin-property-webauthn-class), [RelyingPartyId](#relyingpartyid-property-webauthn-class), and/or [RelyingPartyName](#relyingpartyname-property-webauthn-class) must be set accordingly.

The *Response* parameter is used to provide the JSON-formatted authenticator response returned from the front-end call to *navigator.credentials.create()*.

The *Options* parameter is used to provide the options obtained from [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) during the first step of registration.

After parsing the *Response* and *Options* parameters, the class will first attempt to verify the *Response*. During verification, [RegistrationInfo](#registrationinfo-event-webauthn-class) will fire, requesting confirmation regarding the new credential. Within this event, it should be confirmed that the new credential does not already exist for any user. Please see [RegistrationInfo](#registrationinfo-event-webauthn-class) for additional information.

Assuming the response is successfully verified, [RegistrationComplete](#registrationcomplete-event-webauthn-class) will fire containing information about the new credential, which must be stored for future use. Afterwards, this method will return successfully, indicating the registration process is complete.

Please see below for a simple example of this process:

```csharp
server.OnRegistrationInfo += (o, e) => {
  // Some List of WACredential type, search by Credential Id
  existingCredentials = QueryCredentialsById(e.CredentialId);

  if (existingCredentials.Count != 0) {
    // Registration should fail since CredentialId exists
    e.Cancel = true;
  }
};

server.OnRegistrationComplete += (o, e) => {
  // Save credential info for authentication
  SaveCredential(server.UserName, e.CredentialIdB, e.PublicKey, e.SignCount, e.Algorithm);
};

string response = StreamReader(context.Request.Body).ReadToEnd();
string cachedOptions = context.Session.GetString("registrationOptions") ?? String.Empty;

server.VerifyRegistrationResponse(response, options);

Console.WriteLine("Registration Successful.");
```

# AuthenticationComplete Event ([WebAuthn](#webauthn-class) Class)

Fired when a user successfully logs in.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void authenticationComplete(WebAuthnAuthenticationCompleteEvent e) {}
  ...
}

public class WebAuthnAuthenticationCompleteEvent {
  public byte[] credentialId;
  public int signCount;
}
```

## Remarks

This event is fired when a user successfully logs in, i.e., after [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class) returns without error.

The *CredentialId* parameter should be used to identify the locally stored credential that has been used to successfully log in.

Once the stored credential is identified, the signature counter of this credential record should be updated to the value in the *SignCount* parameter.

If stored previously, implementations may also query the [BackupState](#BackupState) and [UvInitialized](#UvInitialized) configs to update the credential record accordingly.

# AuthenticationInfo Event ([WebAuthn](#webauthn-class) Class)

Fired when the class requests additional information regarding the existing credential.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void authenticationInfo(WebAuthnAuthenticationInfoEvent e) {}
  ...
}

public class WebAuthnAuthenticationInfoEvent {
  public byte[] credentialId;
  public boolean cancel; //read-write
  public String publicKey; //read-write
  public String algorithm; //read-write
  public int signCount; //read-write
}
```

## Remarks

This event is fired when the class requests additional information regarding the existing credential after calling [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class).

The *CredentialId* parameter specifies the credential Id of the existing credential.

The *Cancel* parameter may be utilized to cancel the authentication of the current user or credential.

To handle this event appropriately, the *CredentialId* parameter should be utilized to check the existing credential database. If the credential does not exist in the database, authentication should fail, and the *Cancel* parameter should be set to true.

Otherwise, if the credential exists, *PublicKey*, *Algorithm*, and *SignCount* should be set to their relevant values associated with the credential. Additionally, the [UserName](#username-property-webauthn-class) (and possibly [UserId](#userid-property-webauthn-class)) should be set to their relevant values. The class will utilize these to complete the verification and authentication process.

If stored previously, implementations may optionally set the [BackupEligible](#BackupEligible) config for use during verification.

# Error Event ([WebAuthn](#webauthn-class) Class)

Fired when information is available about errors during data delivery.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void error(WebAuthnErrorEvent e) {}
  ...
}

public class WebAuthnErrorEvent {
  public int errorCode;
  public String description;
}
```

## Remarks

The Error event is fired in case of exceptional conditions during message processing. Normally the class throws an exception.

The *ErrorCode* parameter contains an error code, and the *Description* parameter contains a textual description of the error. For a list of valid error codes and their descriptions, please refer to the [Error Codes](#trappable-errors-webauthn-class) section.

# Extension Event ([WebAuthn](#webauthn-class) Class)

Fired when an extension is found while verifying an authenticator response.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void extension(WebAuthnExtensionEvent e) {}
  ...
}

public class WebAuthnExtensionEvent {
  public String name;
  public String value;
  public int valueType;
}
```

## Remarks

This event is fired when an extension is found while verifying an authenticator response using either [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) or [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class). Any extensions from the parsed response will be added to the [Extensions](#extensions-property-webauthn-class) collection and may be manually verified in [RegistrationInfo](#registrationinfo-event-webauthn-class) or [AuthenticationInfo](#authenticationinfo-event-webauthn-class).

The *Name* parameter specifies the name of the extension.

The *Value* parameter specifies the value of the extension.

The *ValueType* parameter specifies the type of the value. Possible values are as follows:

- 0 (Object)
- 1 (Array)
- 2 (String)
- 3 (Number)
- 4 (Bool)
- 5 (Null)
- 6 (Raw)

The class will not interpret the extensions found, and it will be up to the developer to interpret the extensions accordingly. For more information and an example, please see [AddExtension](#addextension-method-webauthn-class).

# Log Event ([WebAuthn](#webauthn-class) Class)

Fired once for each log message.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void log(WebAuthnLogEvent e) {}
  ...
}

public class WebAuthnLogEvent {
  public int logLevel;
  public String message;
  public String logType;
}
```

## Remarks

This event is fired once for each log message generated by the class. The verbosity is controlled by the [LogLevel](#LogLevel) setting.

*LogLevel* indicates the level of message. Possible values are as follows:

|  |  |
| --- | --- |
| 0 (None) | No events are logged. |
| 1 (Info - default) | Informational events are logged. |
| 2 (Verbose) | Detailed data are logged. |
| 3 (Debug) | Debug data are logged. |

The value 1 (Info) logs basic information, including the URL, HTTP version, and status details.

The value 2 (Verbose) logs additional information about the request and response.

The value 3 (Debug) logs the headers and body for both the request and response, as well as additional debug information (if any).

*Message* is the log entry.

*LogType* identifies the type of log entry. Possible values are as follows:

- "Info"
- "RequestHeaders"
- "ResponseHeaders"
- "RequestBody"
- "ResponseBody"
- "ProxyRequest"
- "ProxyResponse"
- "FirewallRequest"
- "FirewallResponse"

# RegistrationComplete Event ([WebAuthn](#webauthn-class) Class)

Fired when a user is successfully registered.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void registrationComplete(WebAuthnRegistrationCompleteEvent e) {}
  ...
}

public class WebAuthnRegistrationCompleteEvent {
  public byte[] credentialId;
  public String userName;
  public String publicKey;
  public int signCount;
  public String algorithm;
}
```

## Remarks

This event is fired when a user is successfully registered, i.e., after [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) returns without error.

The *CredentialId* parameter indicates the credential Id of the new credential associated with the current *UserName*.

Along with the credential Id, the *PublicKey*, *SignCount*, and *Algorithm* parameters must be stored for future use. Specifically, these parameters will be utilized during authentication, when [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class) is called. These parameters should be directly associated with the specific user this credential was created for.

Implementations may optionally store the [BackupState](#BackupState), [BackupEligible](#BackupEligible), [UvInitialized](#UvInitialized) configs for future use. Please refer to the config descriptions for additional details.

# RegistrationInfo Event ([WebAuthn](#webauthn-class) Class)

Fired when the class requests additional information regarding the new credential.

## Syntax

```text
public class DefaultWebAuthnEventListener implements WebAuthnEventListener {
  ...
  public void registrationInfo(WebAuthnRegistrationInfoEvent e) {}
  ...
}

public class WebAuthnRegistrationInfoEvent {
  public byte[] credentialId;
  public boolean cancel; //read-write
}
```

## Remarks

This event is fired when the class requests additional information regarding the new credential after calling [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class).

The *Cancel* parameter may be utilized to cancel the authentication of the current user or credential.

To handle this event appropriately, the *CredentialId* parameter should be utilized to check the existing credential database. If the credential Id already exists in the database for **any** user, this implies that registration should fail. In this case, the *Cancel* parameter should be set to true.

Otherwise, if the credential Id does not exist in the existing credential database, the *Cancel* parameter should not be modified, and verification will succeed.

# WACredential Type

Represents a WebAuthn credential record.

## Remarks

This type represents a WebAuthn credential record.

The following fields are available:

- [Id](#WACredential_f_Id)

- [PublicKey](#WACredential_f_PublicKey)

- [SignAlgorithm](#WACredential_f_SignAlgorithm)

- [SignCount](#WACredential_f_SignCount)

## Fields

 **Id** *String*
*Default Value: ""*

Specifies the credential Id of the credential.

 **IdB** *byte[]*
*Default Value: ""*

Specifies the credential Id of the credential.

 **PublicKey** *String*
*Default Value: ""*

Specifies the public key of the credential.

 **SignAlgorithm** *String*
*Default Value: "0"*

Specifies the signing algorithm of the credential.

 **SignCount** *int*
*Default Value: 0*

Specifies the signature count of the credential.

## Constructors

```text
public WACredential();
```

# WAExtension Type

Represents an extension that will either be sent to the client and authenticator, or has been received from the client and authenticator.

## Remarks

This type represents an extension that will either be sent to the client and authenticator, or has been received from the client and authenticator.

The following fields are available:

- [Name](#WAExtension_f_Name)

- [Value](#WAExtension_f_Value)

- [ValueType](#WAExtension_f_ValueType)

## Fields

 **Name** *String (read-only)*
*Default Value: ""*

Specifies the name of the extension.

 **Value** *String (read-only)*
*Default Value: ""*

Specifies the value of the extension. See [ValueType](#WAExtension_f_ValueType) for information regarding this fields type.

 **ValueType** *int (read-only)*
*Default Value: 0*

Specifies the type of the [Value](#WAExtension_f_Value) of the current extension. Possible values are:

- 0 (Object)
- 1 (Array)
- 2 (String)
- 3 (Number)
- 4 (Bool)
- 5 (Null)
- 6 (Raw)

## Constructors

```text
public WAExtension();
```

# Config Settings ([WebAuthn](#webauthn-class) Class)

 The class accepts one or more of the following *configuration settings*. Configuration settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these *internal properties* is provided through the [Config](#config-method-webauthn-class) method.

### WebAuthn Config Settings

**BackupEligible**: Indicates or specifies the backup eligibility of a credential.This config indicates or specifies the backup eligibility of a credential, and may be set and/or queried during both registration and authentication. Possible values are:

- *0*: The credential is a single-device credential and may never be backed up.
- *1*: The credential is a multi-device credential and may be backed up.

During registration, this config may be queried within [RegistrationComplete](#registrationcomplete-event-webauthn-class) (or after [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) returns) in order to store the backup eligibility of the new credential for future use.

During authentication, this config may first be set during [AuthenticationInfo](#authenticationinfo-event-webauthn-class) for use during verification of the existing credential. By default, this config will be set to *-1*, implying that backup eligibility will not be utilized during verification.

After verification, this config may be queried within [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) in order to update the stored backup eligibility of the existing credential.

It is recommended to store the value of this flag along with the relevant credential for future evaluation, though not required.

**BackupState**: Indicates the backup state of a credential.This config indicates the backup state of a credential, and may be queried during both registration and authentication. Possible values are:

- *0*: The credential is not currently backed up.
- *1*: The credential is currently backed up.

During registration, this config may be queried within [RegistrationComplete](#registrationcomplete-event-webauthn-class) (or after [VerifyRegistrationResponse](#verifyregistrationresponse-method-webauthn-class) returns) in order to store the backup state of the new credential for future use.

During authentication, this config may be queried within [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) (or after [VerifyAuthenticationResponse](#verifyauthenticationresponse-method-webauthn-class) returns) in order to update the stored backup state of the existing credential.

It is recommended to store the value of this flag along with the relevant credential for future evaluation, though not required.

**Hints**: Specifies any hints to communicate to the user-agent about how a request may be completed.This config may be used to specify any hints to communicate to the user-agent about how a request may be completed. Note that hints do not indicate any requirements from the Relying Party, but may guide the user-agent in providing the best experience by using contextual information the Relying Party has about the request.

This config may be specified as a comma-separated list of one or more of the following values in order of decreasing preference:

- *security-key*: Indicates that the Relying Party believes that users will satisfy this request with a physical security key.
- *client-device*: Indicates that the Relying Party believes that users will satisfy this request with a platform authenticator attached to the client device.
- *hybrid*: Indicates that the Relying Party believes that users will satisfy this request with general-purpose authenticators such as smartphones.

For example, this config may be set to the following string: *security-key,client-device,hybrid*

**ServerChallenge**: Specifies the cryptographic challenge associated with the current options, as specified by the class.This config specifies the cryptographic challenge associated with the current options, as specified by the class.

The cryptographic challenge is some randomly generated data that is sent to the authenticator.

After calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class) or [CreateAuthenticationRequest](#createauthenticationrequest-method-webauthn-class), this may be queried to get the challenge specified in the recently created options.

**UvInitialized**: Indicates whether user verification has been performed for a new or existing credential.This config indicates whether user verification has been successfully performed for a credential. When *true*, user verification has been successfully performed. Otherwise, a value of *false* indicates that either user verification was unsuccessful, or user verification has not been performed at all.

The class can indicate whether it would like user verification to occur by setting the [UserVerification](#userverification-property-webauthn-class) property before calling [CreateRegistrationRequest](#createregistrationrequest-method-webauthn-class). This config may be queried during [RegistrationComplete](#registrationcomplete-event-webauthn-class) or [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) to determine the current user verification status of the relevant credential.

This config may be stored or updated during [RegistrationComplete](#registrationcomplete-event-webauthn-class) or [AuthenticationComplete](#authenticationcomplete-event-webauthn-class) for future use.

### Base Config Settings

**BuildInfo**: Information about the product's build.When queried, this setting will return a string containing information about the product's build.

**GUIAvailable**: Whether or not a message loop is available for processing events.In a GUI-based application, long-running blocking operations may cause the application to stop responding to input until the operation returns. The class will attempt to discover whether or not the application has a message loop and, if one is discovered, it will process events in that message loop during any such blocking operation.

In some non-GUI applications, an invalid message loop may be discovered that will result in errant behavior. In these cases, setting [GUIAvailable](#GUIAvailable) to *false* will ensure that the class does not attempt to process external events.

**LicenseInfo**: Information about the current license.When queried, this setting will return a string containing information about the license this instance of a class is using. It will return the following information:

- Product: The product the license is for.
- Product Key: The key the license was generated from.
- License Source: Where the license was found (e.g., RuntimeLicense, License File).
- License Type: The type of license installed (e.g., Royalty Free, Single Server).
- Last Valid Build: The last valid build number for which the license will work.

**MaskSensitiveData**: Whether sensitive data is masked in log messages.In certain circumstances it may be beneficial to mask sensitive data, like passwords, in log messages. Set this to *true* to mask sensitive data. The default is *true*.

**UseDaemonThreads**: Whether threads created by the class are daemon threads.If set to True (default), when the class creates a thread, the thread's Daemon property will be explicitly set to True. When set to False, the class will not set the Daemon property on the created thread. The default value is True.

**UseFIPSCompliantAPI**: Tells the class whether or not to use FIPS certified APIs.When set to *true*, the class will utilize the underlying operating system's certified APIs. Java editions, regardless of OS, utilize Bouncy Castle Federal Information Processing Standards (FIPS), while all other Windows editions make use of Microsoft security libraries.

The Java edition requires installation of the FIPS-certified Bouncy Castle library regardless of the target operating system. This can be downloaded from [https://www.bouncycastle.org/fips-java/](https://www.bouncycastle.org/fips-java/). Only the "Provider" library is needed. The jar file should then be installed in a JRE search path.

The following classes must be imported in the application in which the component will be used:

```text
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
```

The Bouncy Castle provider must be added as a valid provider and must also be configured to operate in FIPS mode:

```text
System.setProperty("org.bouncycastle.fips.approved_only","true");
Security.addProvider(new BouncyCastleFipsProvider());
```

When [UseFIPSCompliantAPI](#UseFIPSCompliantAPI) is *true*, Secure Sockets Layer (SSL)-enabled classes can optionally be configured to use the Transport Layer Security (TLS) Bouncy Castle library. When SSLProvider is set to *sslpAutomatic* (default) or *sslpInternal*, an internal TLS implementation is used, but all cryptographic operations are offloaded to the Bouncy Castle FIPS provider to achieve FIPS-compliant operation. If SSLProvider is set to *sslpPlatform*, the Bouncy Castle JSSE will be used in place of the internal TLS implementation.

To enable the use of the Bouncy Castle JSSE take the following steps in addition to the steps above. Both the Bouncy Castle FIPS provider and the Bouncy Castle JSSE must be configured to use the Bouncy Castle TLS library in FIPS mode. Obtain the Bouncy Castle TLS library from [https://www.bouncycastle.org/fips-java/](https://www.bouncycastle.org/fips-java/). The jar file should then be installed in a JRE search path.

The following classes must be imported in the application in which the component will be used:

```text
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

//required to use BCJSSE when SSLProvider is set to sslpPlatform
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
```

The Bouncy Castle provider must be added as a valid provider and also must be configured to operate in FIPS mode:

```text
System.setProperty("org.bouncycastle.fips.approved_only","true");
Security.addProvider(new BouncyCastleFipsProvider());

//required to use BCJSSE when SSLProvider is set to sslpPlatform
Security.addProvider(new BouncyCastleJsseProvider("fips:BCFIPS"));

//optional - configure logging level of BCJSSE
Logger.getLogger("org.bouncycastle.jsse").setLevel(java.util.logging.Level.OFF);

//configure the class to use BCJSSE
component.setSSLProvider(1); //platform
component.config("UseFIPSCompliantAPI=true");
```

 NOTE: TLS 1.3 support requires the Bouncy Castle TLS library version 1.0.14 or later.

FIPS mode can be enabled by setting the *UseFIPSCompliantAPI* configuration setting to *true*. This is a static setting that applies to all instances of all classes of the toolkit within the process. It is recommended to enable or disable this setting once before the component has been used to establish a connection. Enabling FIPS while an instance of the component is active and connected may result in unexpected behavior.

For more details, please see the [FIPS 140-2 Compliance](https://www.nsoftware.com/kb/articles/fips.rst) article.

NOTE: Enabling FIPS compliance requires a special license; please contact [sales@nsoftware.com](mailto:sales@nsoftware.com) for details.

**UseInternalSecurityAPI**: Whether or not to use the system security libraries or an internal implementation. When set to *false*, the class will use the system security libraries by default to perform cryptographic functions where applicable.

Setting this configuration setting to *true* tells the class to use the internal implementation instead of using the system security libraries.

 This setting is set to *false* by default on all platforms.

**UseVirtualThreads**: Whether threads created by the class use virtual threads instead of platform threads.If set to *true*, when the class creates a thread, it will be created as a virtual thread instead of a platform thread. Virtual threads are lightweight threads managed by the JVM that are multiplexed onto a small pool of carrier threads, significantly reducing memory usage and platform thread count under high-concurrency workloads. Requires Java 24 or later. The default value is *false*.

# Trappable Errors ([WebAuthn](#webauthn-class) Class)
