Passwordless and WebAuthn
Relevant source files
The following files were used as context for generating this wiki page:
Passwordless authentication in Casdoor is primarily implemented through the WebAuthn (Web Authentication) standard, allowing users to register and sign in using biometrics or security keys. This system provides a more secure and convenient alternative to traditional password-based authentication by leveraging public-key cryptography. Sources: README.md, web/src/Setting.js:1015-1017
The implementation follows the W3C WebAuthn standard, consisting of a registration flow (signup) and an authentication flow (signin). Users can manage multiple WebAuthn credentials within their profile, which are stored as part of the user's object in the database. Sources: controllers/webauthn.go:27-28, web/src/table/WebauthnCredentialTable.js
Architecture and Data Flow
The WebAuthn system is divided into frontend handlers that interact with the browser's navigator.credentials API and backend controllers that manage challenges and verify cryptographic assertions. Sources: web/src/backend/UserWebauthnBackend.js:19-35, controllers/webauthn.go:30-45
Registration Flow (Signup)
Registration involves two stages: "Begin" and "Finish". In the first stage, the server generates CredentialCreationOptions, which includes a unique challenge. The browser uses these options to prompt the user for a biometric or hardware token. In the second stage, the server verifies the resulting attestation and stores the public key. Sources: web/src/backend/UserWebauthnBackend.js:19-54, swagger/swagger.yml:1134-1153
The registration process requires the user to be logged in to associate the new credential with an existing account. Sources: web/src/backend/UserWebauthnBackend.js:19-21, controllers/webauthn.go:30-33
Authentication Flow (Signin)
Similar to registration, authentication uses a two-stage process. The "Begin" stage provides the browser with a list of allowed credentials and a challenge. The user provides a cryptographic assertion via their authenticator, which the server verifies in the "Finish" stage to grant access. Sources: swagger/swagger.yml:1107-1132, routers/router.go:235-236
The signin flow uses the CredentialAssertion and CredentialAssertionResponse objects to exchange verification data. Sources: swagger/swagger.yml:1107-1132, controllers/webauthn.go:132-135
Key Components and Data Structures
API Endpoints
The following table summarizes the primary API endpoints used for Passwordless and WebAuthn operations. Sources: routers/router.go:233-236, swagger/swagger.yml:1107-1153
| Endpoint | Method | Description |
|---|---|---|
/api/webauthn/signup/begin | GET | Initiates the registration process and returns challenge options. |
/api/webauthn/signup/finish | POST | Completes registration by verifying and saving the credential. |
/api/webauthn/signin/begin | GET | Initiates the authentication process for a specific user. |
/api/webauthn/signin/finish | POST | Verifies the authentication assertion to log the user in. |
Data Models
WebAuthn credentials are stored within the User object. Each credential contains identifying information, the public key, and metadata like the sign count to prevent replay attacks. Sources: object/user_webauthn.go:25-36, swagger/swagger.yml:1642-1644
The internal representation uses the webauthn.Credential type defined in the backend. Sources: swagger/swagger.yml:1642-1644, object/user_webauthn.go:25-30
User Interface and Management
Users manage their WebAuthn credentials through a dedicated table in their profile. This interface allows for adding new credentials and removing existing ones. Sources: web/src/table/WebauthnCredentialTable.js:33-40
Credential Table Fields
| Field | Description |
|---|---|
| Name | A user-defined label for the credential (e.g., "My YubiKey"). |
| Created Time | The timestamp when the credential was registered. |
| ID | The unique identifier for the credential generated by the authenticator. |
| Action | Options to delete the specific credential. |
Sources: web/src/table/WebauthnCredentialTable.js:77-120
Configuration
WebAuthn must be enabled within the application settings for users to use this authentication method. Administrators can toggle this via the enableWebAuthn boolean field in the Application configuration. Sources: web/src/Setting.js:1015-1017, swagger/swagger.yml:1288-1289
Cryptographic Implementation Details
The system uses Base64URL encoding to transport binary buffers between the browser and the server. The webAuthnBufferDecode and webAuthnBufferEncode helper functions handle these conversions on the frontend. Sources: web/src/backend/UserWebauthnBackend.js:63-79
// Base64URL to ArrayBuffer conversion for WebAuthn challenges
export function webAuthnBufferDecode(value) {
value = value.replace(/-/g, "+").replace(/_/g, "/");
while (value.length % 4) {
value += "=";
}
return Uint8Array.from(atob(value), c => c.charCodeAt(0));
}
Sources: web/src/backend/UserWebauthnBackend.js:63-71
Conclusion
The Passwordless and WebAuthn system in Casdoor provides a robust framework for biometric and hardware-based authentication. By integrating the two-stage WebAuthn protocol directly into the user management flow, it enables high-security login options that are resilient to phishing and credential theft. Sources: README.md, controllers/webauthn.go:27-28