| File: IPasskeyHandler.cs | Web Access |
| Project: src\aspnetcore\src\Identity\Core\src\Microsoft.AspNetCore.Identity.csproj (Microsoft.AspNetCore.Identity) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Identity; /// <summary> /// Represents a handler for generating passkey creation and request options and performing /// passkey assertion and attestation. /// </summary> public interface IPasskeyHandler<TUser> where TUser : class { /// <summary> /// Gets a value indicating whether this handler supports generating passkey signal options. /// </summary> /// <remarks> /// Returns <see langword="false"/> unless the handler implements /// <see cref="MakeAllAcceptedCredentialsSignalOptionsAsync(TUser, HttpContext)"/> and /// <see cref="MakeCurrentUserDetailsSignalOptionsAsync(TUser, PasskeyUserEntity, HttpContext)"/> /// and can retrieve the user's passkeys. /// </remarks> bool SupportsPasskeySignalOptions => false; /// <summary> /// Generates passkey creation options for the specified user entity and HTTP context. /// </summary> /// <param name="userEntity">The passkey user entity for which to generate creation options.</param> /// <param name="httpContext">The HTTP context associated with the request.</param> /// <returns>A <see cref="PasskeyCreationOptionsResult"/> representing the result.</returns> Task<PasskeyCreationOptionsResult> MakeCreationOptionsAsync(PasskeyUserEntity userEntity, HttpContext httpContext); /// <summary> /// Generates passkey request options for the specified user and HTTP context. /// </summary> /// <param name="user">The user for whom to generate request options.</param> /// <param name="httpContext">The HTTP context associated with the request.</param> /// <returns>A <see cref="PasskeyRequestOptionsResult"/> representing the result.</returns> Task<PasskeyRequestOptionsResult> MakeRequestOptionsAsync(TUser? user, HttpContext httpContext); /// <summary> /// Generates the options used to signal the credentials that are currently registered for a user. /// </summary> /// <remarks> /// <para> /// Handlers that implement this method should also return <see langword="true"/> from /// <see cref="SupportsPasskeySignalOptions"/>. See <see href="https://www.w3.org/TR/webauthn-3/#sctn-signal-methods"/>. /// </para> /// <para> /// The generated options reveal the user's credential IDs, so only generate them for the /// currently authenticated user. /// </para> /// </remarks> /// <param name="user">The user whose passkeys should be signaled.</param> /// <param name="httpContext">The HTTP context associated with the request.</param> /// <returns>An <see cref="AllAcceptedCredentialsSignalOptionsResult"/> representing the result.</returns> /// <exception cref="NotSupportedException">Thrown when the handler does not support generating passkey signal options.</exception> Task<AllAcceptedCredentialsSignalOptionsResult> MakeAllAcceptedCredentialsSignalOptionsAsync(TUser user, HttpContext httpContext) => throw new NotSupportedException($"'{GetType()}' does not support generating passkey signal options."); /// <summary> /// Generates the options used to signal the current details of a user. /// </summary> /// <remarks> /// <para> /// Handlers that implement this method should also return <see langword="true"/> from /// <see cref="SupportsPasskeySignalOptions"/>. See <see href="https://www.w3.org/TR/webauthn-3/#sctn-signal-methods"/>. /// </para> /// <para> /// The generated options reveal the user's details, so only generate them for the /// currently authenticated user. /// </para> /// </remarks> /// <param name="user">The user whose details should be signaled.</param> /// <param name="userEntity"> /// The passkey user entity associated with the user's passkeys. Its <see cref="PasskeyUserEntity.Id"/> /// must match the ID of <paramref name="user"/>. The <see cref="PasskeyUserEntity.Name"/> and /// <see cref="PasskeyUserEntity.DisplayName"/> are the values being signaled. /// </param> /// <param name="httpContext">The HTTP context associated with the request.</param> /// <returns>A <see cref="CurrentUserDetailsSignalOptionsResult"/> representing the result.</returns> /// <exception cref="NotSupportedException">Thrown when the handler does not support generating passkey signal options.</exception> Task<CurrentUserDetailsSignalOptionsResult> MakeCurrentUserDetailsSignalOptionsAsync(TUser user, PasskeyUserEntity userEntity, HttpContext httpContext) => throw new NotSupportedException($"'{GetType()}' does not support generating passkey signal options."); /// <summary> /// Generates options used to signal that a passkey credential is unknown to the server. /// </summary> /// <remarks> /// <para> /// The signal permanently deletes the passkey from the browser's passkey provider. A handler must only return /// options when the credential is not registered to any user on the server. /// See <see href="https://www.w3.org/TR/webauthn-3/#sctn-signal-methods"/>. /// </para> /// <para> /// Unlike <see cref="MakeAllAcceptedCredentialsSignalOptionsAsync(TUser, HttpContext)"/>, an incorrect signal /// may permanently delete a working passkey. A handler must only return options after conclusively determining /// that the credential is not registered to any user. An inconclusive lookup must not produce signal options. /// </para> /// </remarks> /// <param name="credentialJson">The JSON representation of the passkey credential.</param> /// <param name="httpContext">The HTTP context associated with the request.</param> /// <returns> /// An <see cref="UnknownCredentialSignalOptionsResult"/> when the credential is unknown to the server, /// otherwise <see langword="null"/>. /// </returns> Task<UnknownCredentialSignalOptionsResult?> MakeUnknownCredentialSignalOptionsAsync(string credentialJson, HttpContext httpContext) => Task.FromResult<UnknownCredentialSignalOptionsResult?>(null); /// <summary> /// Performs passkey attestation using the provided <see cref="PasskeyAttestationContext"/>. /// </summary> /// <param name="context">The context containing necessary information for passkey attestation.</param> /// <returns>A <see cref="PasskeyAttestationResult"/> representing the result.</returns> Task<PasskeyAttestationResult> PerformAttestationAsync(PasskeyAttestationContext context); /// <summary> /// Performs passkey assertion using the provided <see cref="PasskeyAssertionContext"/>. /// </summary> /// <param name="context">The context containing necessary information for passkey assertion.</param> /// <returns>A <see cref="PasskeyAssertionResult{TUser}"/> representing the result.</returns> Task<PasskeyAssertionResult<TUser>> PerformAssertionAsync(PasskeyAssertionContext context); }