FIDO2 APIs for React Native Applications
Ideem's FIDO2Client provides an abstraction for integrating with WebAuthn and FIDO2 authentication in your React Native application. It simplifies managing interactions with a Relying Party (RP), handling user enrollment, and verifying authentication challenges.
The FIDO2Client handles:
- Checking if a user is enrolled (linked to a cryptographically bound account).
- Creating new credentials (user enrollment).
- Verifying existing credentials during authentication.
- Supporting step-up authentication for sensitive operations.
This document details the core methods and best practices for using the FIDO2Client.
Relying Party Overview
A Relying Party (RP) is a server or service that initiates WebAuthn-based authentication. The RP generates cryptographic challenges for user registration or login and verifies the returned signatures using stored credentials.
The steps typically involve:
- Registration: The RP generates a challenge and sends it to the user’s authenticator. Once the credential is created, the RP stores the credential ID and public key for future use.
- Authentication: The RP sends a challenge to the user's authenticator, receives a signed response, and verifies it using the associated public key.
The FIDO2Client abstracts these steps into simple methods, letting developers focus on integration.
Interface Definitions
Before proceeding, ensure you have imported the FIDO2Client from the ZSM React Native SDK:
import { FIDO2Client } from '@ideem/zsm-react-native';
Webauthn Retrieve: FIDO2Client.webauthnRetrieve()
This method retrieves the WebAuthn credential for a user, enabling the Relying Party to verify their enrollment status.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
username | string | The username or identifier for the user. |
Returns
| Parameter Name | Data Type | Description |
|---|---|---|
response | PublicKeyCredential | Contains the user’s WebAuthn attestation data. |
Usage Example
client
.webauthnRetrieve('exampleuser')
.then((credential) => {
console.log('Credential retrieved:', credential);
})
.catch((error) => {
console.error('Error retrieving credential:', error.message);
});
Webauthn Create: FIDO2Client.webauthnCreate()
This method registers a new WebAuthn credential for the user. It generates a key pair and securely binds the private key to the user and their device.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
username | string | The username or identifier for the user. |
Returns
| Parameter Name | Data Type | Description |
|---|---|---|
credential | PublicKeyCredential | The newly created WebAuthn credential object. |
Usage Example
client
.webauthnCreate('exampleuser')
.then((credential) => {
console.log('Credential created successfully:', credential);
})
.catch((error) => {
console.error('Error creating credential:', error.message);
});
Webauthn Get: FIDO2Client.webauthnGet()
This method authenticates a user by requesting their authenticator to sign a cryptographic challenge. The Relying Party verifies the signed response using the stored public key.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
username | string | The username or identifier for the user. |
Returns
| Parameter Name | Data Type | Description |
|---|---|---|
assertion | PublicKeyCredential | The signed WebAuthn credential assertion object. |
Usage Example
client
.webauthnGet('exampleuser')
.then((result) => {
console.log('Authentication successful:', result);
})
.catch((error) => {
console.error('Error during authentication:', error.message);
});
Example Code
Example of Default Flow: Registration and Authentication
Here’s a complete flow using the default Relying Party:
const client = new FIDO2Client(config);
const username = 'exampleuser';
// Check if the user is enrolled, and if not, create a credential
client
.checkIdentity(username, true)
.then(() => {
console.log('Identity check complete');
return client.webauthnCreate(username);
})
.then((credential) => {
console.log('Credential created successfully:', credential);
return client.webauthnGet(username);
})
.then((result) => {
console.log('Authentication successful:', result);
})
.catch((error) => {
console.error('Error in flow:', error.message);
});
Custom Relying Party Example
If you need more control, create a custom Relying Party to handle credential storage and management:
class CustomRelyingParty {
constructor(apiHost) {
this.apiHost = apiHost;
}
async startRegistration(userId) {
const response = await fetch(`${this.apiHost}/registration/start`, {
method: 'POST',
body: JSON.stringify({ userId }),
});
return response.json();
}
async finishRegistration(userId, credential) {
const response = await fetch(`${this.apiHost}/registration/finish`, {
method: 'POST',
body: JSON.stringify({ userId, credential }),
});
return response.json();
}
}
const customRelyingParty = new CustomRelyingParty('https://custom-rp.example.com');
const client = new FIDO2Client({ relyingParty: customRelyingParty });
client
.checkIdentity('exampleuser', true)
.then(() => console.log('Identity verified'))
.catch((error) => console.error('Error verifying identity:', error.message));
Explanation
The FIDO2Client simplifies the integration of FIDO2 and WebAuthn by abstracting complex interactions with authenticators and Relying Parties. Below is a breakdown of how its key features work together:
-
Checking Identity:
- The
checkIdentitymethod ensures that the user's identity is either already registered or creates a new one if necessary. This serves as the first step in establishing a secure association between the user and the application.
- The
-
Creating Credentials:
- Using
webauthnCreate, the client generates a new cryptographic credential for the user. This step involves securely binding the credential to the user’s device, ensuring the private key never leaves the authenticator.
- Using
-
Retrieving Credentials:
- The
webauthnRetrievemethod allows the client to fetch stored credentials linked to the user. This is critical for verifying enrollment and determining the appropriate next step in the authentication process.
- The
-
Authentication:
- The
webauthnGetmethod facilitates secure user authentication by leveraging the stored credential. The authenticator signs a cryptographic challenge, which is verified by the Relying Party to confirm the user’s identity.
- The
-
Relying Party Abstraction:
- The
FIDO2Clientworks seamlessly with a default Relying Party setup but also allows for custom Relying Party implementations. This flexibility ensures the SDK can adapt to various backend architectures.
- The
-
Security and Compliance:
- By adhering to FIDO2 and WebAuthn standards, the client ensures secure and phishing-resistant authentication. Developers can integrate these advanced security features without needing deep expertise in cryptography or authentication protocols.
By following the default flow or implementing a custom Relying Party, developers can build robust, secure authentication workflows with minimal effort.
Summary
The FIDO2Client provides a simple and flexible way to integrate WebAuthn into your React Native applications. Its methods for credential management and authentication abstract the complexities of the FIDO2/WebAuthn standard, letting you focus on building secure user experiences.
For advanced use cases, such as custom Relying Party integration, the FIDO2Client offers extensibility while adhering to FIDO2 security standards.