loading

Check availability

IsAvailable

Returns true when the browser exposes the Web Authentication API. WebAuthn requires a secure context, so expect false on plain http origins (localhost is exempt).

C#
@inject Bit.Butil.WebAuthn webAuthn

var isAvailable = await webAuthn.IsAvailable();
Live sample
availability output
Results will appear here when you interact with the samples.

Create a passkey credential

CreateCredential

Registers a new public-key credential with a platform authenticator (Windows Hello, Touch ID, Android biometrics). The options object mirrors PublicKeyCredentialCreationOptions; Butil accepts any serializable shape - anonymous objects, JsonElement or your own typed classes via the generic overload. The returned JsonElement carries the credential id, rawId and attestation response.

C#
var result = await webAuthn.CreateCredential(new
{
    challenge = "testChallenge",
    rp = new { name = "testRp" },
    attestation = "direct",
    user = new { id = "userId", name = "testUser", displayName = "testUser" },
    authenticatorSelection = new { authenticatorAttachment = "platform" },
    pubKeyCredParams = new object[]
    {
        new { alg = -7, type = "public-key" },   // ES256
        new { alg = -8, type = "public-key" },   // Ed25519
        new { alg = -257, type = "public-key" }  // RS256
    }
});

var credentialId = result.GetProperty("id").ToString();
Live sample
create credential output
Results will appear here when you interact with the samples.

Get an assertion

GetCredential

Asks the authenticator to sign a challenge with an existing credential, producing an assertion your server would verify. Passing the previously created rawId in allowCredentials narrows the request to that passkey; an empty list lets the browser offer any discoverable credential for this origin.

C#
var options = createdRawId is null
    ? new { challenge = "test", allowCredentials = new object[] { } }
    : new { challenge = "test", allowCredentials = new object[] { new { id = createdRawId, type = "public-key" } } };

var assertion = await webAuthn.GetCredential(options);

var credentialId = assertion.GetProperty("id").ToString();
Live sample
assertion output
Results will appear here when you interact with the samples.

One-line user verification

Verify

A convenience wrapper for the common re-authentication gesture: on first call it creates a Butil-managed credential and remembers its rawId in LocalStorage; on later calls it requests an assertion for that credential. Returns true when the user completes the native verification, false otherwise. Pass forceCreate to discard the remembered credential and register a fresh one.

C#
var verified = await webAuthn.Verify();

// re-register instead of asserting the remembered credential:
var reRegistered = await webAuthn.Verify(forceCreate: true);
Live sample
verify output
Results will appear here when you interact with the samples.
Warning:
Challenges belong on the server This page uses hard-coded challenges so the demo is self-contained. A real application must generate a cryptographically random challenge server-side for every ceremony, send it to the client, and verify the signed response server-side (for example with the FIDO2 .NET library). A client-only flow proves the user completed a local gesture - it does not authenticate anyone to your backend.
Note:
Secure context and user activation WebAuthn only works on https origins (or localhost) and the browser may require a recent user interaction before showing the passkey prompt. If a call is rejected, the promise fails with a NotAllowedError which surfaces here as a JSException.

API reference

Member
Signature
Description
IsAvailable
Task<bool> IsAvailable()
Checks that the WebAuthentication api is available on the client or not.
CreateCredential
Task<JsonElement> CreateCredential(object options)
Creates a new credential from an arbitrary serializable options object.
CreateCredential
Task<JsonElement> CreateCredential(JsonElement options)
Creates a new credential from a JsonElement options payload.
CreateCredential<TValue, TResult>
Task<TResult> CreateCredential<TValue, TResult>(TValue options)
Typed overload: serializes TValue options and deserializes the credential into TResult.
GetCredential
Task<JsonElement> GetCredential(object options)
Retrieves an assertion for an existing credential from an arbitrary serializable options object.
GetCredential
Task<JsonElement> GetCredential(JsonElement options)
Retrieves an assertion from a JsonElement options payload.
GetCredential<TValue, TResult>
Task<TResult> GetCredential<TValue, TResult>(TValue options)
Typed overload: serializes TValue options and deserializes the assertion into TResult.
Verify
Task<bool> Verify(bool forceCreate = false)
Tries to get a valid credential using the minimum required options to expose a native verification feature. forceCreate registers a new credential instead of asserting the remembered one.
An unhandled error has occurred. Reload 🗙