Skip to content

Commit e3db998

Browse files
committed
Design updates
1 parent a94e3e8 commit e3db998

File tree

48 files changed

+1245
-1786
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1245
-1786
lines changed

src/Identity/Core/src/DefaultPasskeyHandler.cs

Lines changed: 220 additions & 144 deletions
Large diffs are not rendered by default.
Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,44 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Microsoft.AspNetCore.Http;
5+
46
namespace Microsoft.AspNetCore.Identity;
57

68
/// <summary>
7-
/// Represents a handler for passkey assertion and attestation.
9+
/// Represents a handler for generating passkey creation and request options and performing
10+
/// passkey assertion and attestation.
811
/// </summary>
912
public interface IPasskeyHandler<TUser>
1013
where TUser : class
1114
{
1215
/// <summary>
13-
/// Performs passkey attestation using the provided credential JSON and original options JSON.
16+
/// Generates passkey creation options for the specified user entity and HTTP context.
17+
/// </summary>
18+
/// <param name="userEntity">The passkey user entity for which to generate creation options.</param>
19+
/// <param name="httpContext">The HTTP context associated with the request.</param>
20+
/// <returns>A <see cref="PasskeyCreationOptionsResult"/> representing the result.</returns>
21+
Task<PasskeyCreationOptionsResult> MakeCreationOptionsAsync(PasskeyUserEntity userEntity, HttpContext httpContext);
22+
23+
/// <summary>
24+
/// Generates passkey request options for the specified user and HTTP context.
25+
/// </summary>
26+
/// <param name="user">The user for whom to generate request options.</param>
27+
/// <param name="httpContext">The HTTP context associated with the request.</param>
28+
/// <returns>A <see cref="PasskeyRequestOptionsResult"/> representing the result.</returns>
29+
Task<PasskeyRequestOptionsResult> MakeRequestOptionsAsync(TUser? user, HttpContext httpContext);
30+
31+
/// <summary>
32+
/// Performs passkey attestation using the provided <see cref="PasskeyAttestationContext"/>.
1433
/// </summary>
1534
/// <param name="context">The context containing necessary information for passkey attestation.</param>
16-
/// <returns>A task object representing the asynchronous operation containing the <see cref="PasskeyAttestationResult"/>.</returns>
17-
Task<PasskeyAttestationResult> PerformAttestationAsync(PasskeyAttestationContext<TUser> context);
35+
/// <returns>A <see cref="PasskeyAttestationResult"/> representing the result.</returns>
36+
Task<PasskeyAttestationResult> PerformAttestationAsync(PasskeyAttestationContext context);
1837

1938
/// <summary>
20-
/// Performs passkey assertion using the provided credential JSON, original options JSON, and optional user.
39+
/// Performs passkey assertion using the provided <see cref="PasskeyAssertionContext"/>.
2140
/// </summary>
2241
/// <param name="context">The context containing necessary information for passkey assertion.</param>
23-
/// <returns>A task object representing the asynchronous operation containing the <see cref="PasskeyAssertionResult{TUser}"/>.</returns>
24-
Task<PasskeyAssertionResult<TUser>> PerformAssertionAsync(PasskeyAssertionContext<TUser> context);
42+
/// <returns>A <see cref="PasskeyAssertionResult{TUser}"/> representing the result.</returns>
43+
Task<PasskeyAssertionResult<TUser>> PerformAssertionAsync(PasskeyAssertionContext context);
2544
}

src/Identity/Core/src/IdentityJsonSerializerContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace Microsoft.AspNetCore.Identity;
1111
[JsonSerializable(typeof(PublicKeyCredentialRequestOptions))]
1212
[JsonSerializable(typeof(PublicKeyCredential<AuthenticatorAssertionResponse>))]
1313
[JsonSerializable(typeof(PublicKeyCredential<AuthenticatorAttestationResponse>))]
14+
[JsonSerializable(typeof(PasskeyAttestationState))]
15+
[JsonSerializable(typeof(PasskeyAssertionState))]
1416
[JsonSourceGenerationOptions(
1517
JsonSerializerDefaults.Web,
1618
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,

src/Identity/Core/src/PasskeyAssertionContext.cs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ namespace Microsoft.AspNetCore.Identity;
88
/// <summary>
99
/// Represents the context for passkey assertion.
1010
/// </summary>
11-
/// <typeparam name="TUser">The type of user associated with the passkey.</typeparam>
12-
public sealed class PasskeyAssertionContext<TUser>
13-
where TUser : class
11+
public sealed class PasskeyAssertionContext
1412
{
1513
/// <summary>
16-
/// Gets or sets the user associated with the passkey, if known.
14+
/// Gets or sets the <see cref="Http.HttpContext"/> for the current request.
1715
/// </summary>
18-
public TUser? User { get; init; }
16+
public required HttpContext HttpContext { get; init; }
1917

2018
/// <summary>
2119
/// Gets or sets the credentials obtained by JSON-serializing the result of the
@@ -24,17 +22,11 @@ public sealed class PasskeyAssertionContext<TUser>
2422
public required string CredentialJson { get; init; }
2523

2624
/// <summary>
27-
/// Gets or sets the JSON representation of the original passkey creation options provided to the browser.
28-
/// </summary>
29-
public required string OriginalOptionsJson { get; init; }
30-
31-
/// <summary>
32-
/// Gets or sets the <see cref="UserManager{TUser}"/> to retrieve user information from.
25+
/// Gets or sets the state to be used in the assertion procedure.
3326
/// </summary>
34-
public required UserManager<TUser> UserManager { get; init; }
35-
36-
/// <summary>
37-
/// Gets or sets the <see cref="HttpContext"/> for the current request.
38-
/// </summary>
39-
public required HttpContext HttpContext { get; init; }
27+
/// <remarks>
28+
/// This is expected to match the <see cref="PasskeyRequestOptionsResult.AssertionState"/>
29+
/// previously returned from <see cref="IPasskeyHandler{TUser}.MakeRequestOptionsAsync(TUser, HttpContext)"/>.
30+
/// </remarks>
31+
public required string? AssertionState { get; init; }
4032
}

src/Identity/Core/src/PasskeyAttestationContext.cs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,25 @@ namespace Microsoft.AspNetCore.Identity;
88
/// <summary>
99
/// Represents the context for passkey attestation.
1010
/// </summary>
11-
/// <typeparam name="TUser">The type of user associated with the passkey.</typeparam>
12-
public sealed class PasskeyAttestationContext<TUser>
13-
where TUser : class
11+
public sealed class PasskeyAttestationContext
1412
{
1513
/// <summary>
16-
/// Gets or sets the credentials obtained by JSON-serializing the result of the
17-
/// <c>navigator.credentials.create()</c> JavaScript function.
18-
/// </summary>
19-
public required string CredentialJson { get; init; }
20-
21-
/// <summary>
22-
/// Gets or sets the JSON representation of the original passkey creation options provided to the browser.
14+
/// Gets or sets the <see cref="Http.HttpContext"/> for the current request.
2315
/// </summary>
24-
public required string OriginalOptionsJson { get; init; }
16+
public required HttpContext HttpContext { get; init; }
2517

2618
/// <summary>
27-
/// Gets or sets the <see cref="UserManager{TUser}"/> to retrieve user information from.
19+
/// Gets or sets the credentials obtained by JSON-serializing the result of the
20+
/// <c>navigator.credentials.create()</c> JavaScript function.
2821
/// </summary>
29-
public required UserManager<TUser> UserManager { get; init; }
22+
public required string CredentialJson { get; init; }
3023

3124
/// <summary>
32-
/// Gets or sets the <see cref="HttpContext"/> for the current request.
25+
/// Gets or sets the state to be used in the attestation procedure.
3326
/// </summary>
34-
public required HttpContext HttpContext { get; init; }
27+
/// <remarks>
28+
/// This is expected to match the <see cref="PasskeyCreationOptionsResult.AttestationState"/>
29+
/// previously returned from <see cref="IPasskeyHandler{TUser}.MakeCreationOptionsAsync(PasskeyUserEntity, HttpContext)"/>.
30+
/// </remarks>
31+
public required string? AttestationState { get; init; }
3532
}

src/Identity/Core/src/PasskeyAttestationResult.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public sealed class PasskeyAttestationResult
1414
/// Gets whether the attestation was successful.
1515
/// </summary>
1616
[MemberNotNullWhen(true, nameof(Passkey))]
17+
[MemberNotNullWhen(true, nameof(UserEntity))]
1718
[MemberNotNullWhen(false, nameof(Failure))]
1819
public bool Succeeded { get; }
1920

@@ -22,15 +23,21 @@ public sealed class PasskeyAttestationResult
2223
/// </summary>
2324
public UserPasskeyInfo? Passkey { get; }
2425

26+
/// <summary>
27+
/// Gets the user entity associated with the passkey when successful.
28+
/// </summary>
29+
public PasskeyUserEntity? UserEntity { get; }
30+
2531
/// <summary>
2632
/// Gets the error that occurred during attestation.
2733
/// </summary>
2834
public PasskeyException? Failure { get; }
2935

30-
private PasskeyAttestationResult(UserPasskeyInfo passkey)
36+
private PasskeyAttestationResult(UserPasskeyInfo passkey, PasskeyUserEntity userEntity)
3137
{
3238
Succeeded = true;
3339
Passkey = passkey;
40+
UserEntity = userEntity;
3441
}
3542

3643
private PasskeyAttestationResult(PasskeyException failure)
@@ -43,11 +50,12 @@ private PasskeyAttestationResult(PasskeyException failure)
4350
/// Creates a successful result for a passkey attestation operation.
4451
/// </summary>
4552
/// <param name="passkey">The passkey information associated with the attestation.</param>
53+
/// <param name="userEntity">The user entity associated with the attestation.</param>
4654
/// <returns>A <see cref="PasskeyAttestationResult"/> instance representing a successful attestation.</returns>
47-
public static PasskeyAttestationResult Success(UserPasskeyInfo passkey)
55+
public static PasskeyAttestationResult Success(UserPasskeyInfo passkey, PasskeyUserEntity userEntity)
4856
{
4957
ArgumentNullException.ThrowIfNull(passkey);
50-
return new PasskeyAttestationResult(passkey);
58+
return new PasskeyAttestationResult(passkey, userEntity);
5159
}
5260

5361
/// <summary>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.AspNetCore.Http;
5+
6+
namespace Microsoft.AspNetCore.Identity;
7+
8+
/// <summary>
9+
/// Contains the context for passkey attestation statement verification.
10+
/// </summary>
11+
/// <remarks>
12+
/// See <see href="https://www.w3.org/TR/webauthn-3/#verification-procedure"/>.
13+
/// </remarks>
14+
public readonly struct PasskeyAttestationStatementVerificationContext
15+
{
16+
/// <summary>
17+
/// Gets or sets the <see cref="HttpContext"/> for the current request.
18+
/// </summary>
19+
public required HttpContext HttpContext { get; init; }
20+
21+
/// <summary>
22+
/// Gets or sets the attestation object as a byte array.
23+
/// </summary>
24+
/// <remarks>
25+
/// See <see href="https://www.w3.org/TR/webauthn-3/#attestation-object"/>.
26+
/// </remarks>
27+
public required ReadOnlyMemory<byte> AttestationObject { get; init; }
28+
29+
/// <summary>
30+
/// Gets or sets the hash of the client data as a byte array.
31+
/// </summary>
32+
public required ReadOnlyMemory<byte> ClientDataHash { get; init; }
33+
}

src/Identity/Core/src/PasskeyCreationArgs.cs

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/Identity/Core/src/PasskeyCreationOptions.cs

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Microsoft.AspNetCore.Identity;
5+
6+
/// <summary>
7+
/// Represents the result of a passkey creation options generation.
8+
/// </summary>
9+
public sealed class PasskeyCreationOptionsResult
10+
{
11+
/// <summary>
12+
/// Gets or sets the JSON representation of the creation options.
13+
/// </summary>
14+
/// <remarks>
15+
/// The structure of this JSON is compatible with
16+
/// <see href="https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialcreationoptionsjson"/>
17+
/// and should be used with the <c>navigator.credentials.create()</c> JavaScript API.
18+
/// </remarks>
19+
public required string CreationOptionsJson { get; init; }
20+
21+
/// <summary>
22+
/// Gets or sets the state to be used in the attestation procedure.
23+
/// </summary>
24+
/// <remarks>
25+
/// This can be later retrieved during assertion with <see cref="PasskeyAttestationContext.AttestationState"/>.
26+
/// </remarks>
27+
public string? AttestationState { get; init; }
28+
}

0 commit comments

Comments
 (0)