Repository navigation
Align passkey guidance with the .NET 11 Blazor template - #37559
Conversation
|
Thanks, @rolandVi ... Let me try and get back to you tomorrow (Tuesday). I'm ⛏️😅 at the moment on a doc overhaul. |
|
Fixes #37564 |
guardrex
left a comment
There was a problem hiding this comment.
Thanks for taking care of these updates, @rolandVi! I'm slammed with main doc set overhauls, and you saved me a lot of time submitting this PR.
- There are two NITs inline ... adding a line to get the spacing right in the rendered list and a comma splice.
- For each >=11.0/<11.0 versioned block pair, rotate the >=11.0 blocks to the top of those pairs ... place the >=11.0 content first.
- Finally, run Copilot (Lite) on the PR to see if it turns up anything interesting to adjust.
Co-authored-by: Luke Latham <1622880+guardrex@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates the passkey documentation to better match the .NET 11 Blazor Web App template behavior, primarily by versioning JavaScript snippets and correcting/refreshing related guidance.
Changes:
- Adds monikered JavaScript snippets to differentiate .NET 10 vs .NET 11 flows (notably removing the
headersargument for .NET 11). - Updates guidance around
PasskeySignInAsyncbehavior and refreshes template/source links. - Fixes Blazor guidance for referencing the correct script paths via
@Assets[...]and expands the model-class list for .NET 11.
File summaries
| File | Description |
|---|---|
| aspnetcore/security/authentication/passkeys/index.md | Adds .NET 10/11 monikered JS guidance and updates passkey sign-in behavior documentation. |
| aspnetcore/security/authentication/passkeys/blazor.md | Aligns Blazor template instructions (scripts/links/models) and updates metadata. |
Review details
Suppressed comments (4)
aspnetcore/security/authentication/passkeys/index.md:604
- This Step 6 snippet is described as serializing the credential for submission, but it currently just re-fetches options and calls
navigator.credentials.create()again (same as Step 2/4). It should serialize the created credential (for example viaJSON.stringify) so the reader can submit the JSON to the server.
This issue also appears on line 621 of the same file.
async function createCredential(headers, signal) {
// Step 6: The credential is returned from navigator.credentials.create()
// and is serialized to JSON for submission to the server
const optionsResponse =
await fetchWithErrorHandling('/Account/PasskeyCreationOptions',
aspnetcore/security/authentication/passkeys/index.md:625
- This Step 6 snippet is described as serializing the credential for submission, but it currently just re-fetches options and calls
navigator.credentials.create()again (same as Step 2/4). It should serialize the created credential (for example viaJSON.stringify) so the reader can submit the JSON to the server.
async function createCredential(signal) {
// Step 6: The credential is returned from navigator.credentials.create()
// and is serialized to JSON for submission to the server
const optionsResponse =
await fetchWithErrorHandling('/Account/PasskeyCreationOptions',
aspnetcore/security/authentication/passkeys/index.md:836
- This Step 6 snippet is described as serializing the assertion for submission, but it currently just re-fetches options and calls
navigator.credentials.get()again (same as Step 2/4). It should serialize the returned assertion so the reader can submit the JSON to the server.
This issue also appears on line 853 of the same file.
async function requestCredential(email, mediation, headers, signal) {
// Step 6: The assertion is returned from navigator.credentials.get()
// and is serialized to JSON for submission to the server
const optionsResponse =
await fetchWithErrorHandling(`/Account/PasskeyRequestOptions?username=${email}`,
aspnetcore/security/authentication/passkeys/index.md:857
- This Step 6 snippet is described as serializing the assertion for submission, but it currently just re-fetches options and calls
navigator.credentials.get()again (same as Step 2/4). It should serialize the returned assertion so the reader can submit the JSON to the server.
async function requestCredential(email, mediation, signal) {
// Step 6: The assertion is returned from navigator.credentials.get()
// and is serialized to JSON for submission to the server
const optionsResponse =
await fetchWithErrorHandling(`/Account/PasskeyRequestOptions?username=${email}`,
- Files reviewed: 2/2 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Again, thank you so much for submitting this PR. I'll approve, and I presume that you want to wait to merge it until @rokonec looks at it and provides feedback.
UPDATE: Oh! I see that you removed that review request. In that case, are you ready to merge it now?
Yes, we can merge |
Documents dotnet/aspnetcore#65343, dotnet/aspnetcore#65752, dotnet/aspnetcore#67539 and dotnet/aspnetcore#67589.
The passkey articles had drifted from the Blazor Web App template, so a .NET 11 reader following them copies the .NET 10 flow.
Versioned JavaScript
The .NET 10 samples stay as they are. The .NET 11 versions drop the
headersargument, which the template stopped sending in dotnet/aspnetcore#67589 when it moved to the fetch-metadata CSRF middleware. Those endpoints are still validated, just by the middleware instead of a token header, so nothing loses protection here.The rest
RedirectToInvalidUsersnippet doesn't compile any more, because Update Blazor templates to use TempData aspnetcore#65752 removedRedirectToWithStatusfrom the template. .NET 10 already ships the method, so the section was wrong in both versions. Dropped it.PasskeyAuthenticators.csto the model classes list, missing since Infer passkey display name from AAGUID aspnetcore#65343.PasskeySignInAsyncreturnsSignInResult.Failedon expired session state instead of throwing, per SignInManager: return SignInResult.Failed for expired passkey session challenge aspnetcore#67539.Two things I left out on purpose: the creation options URL moving to
/Account/Manage/, andPasskeyOperationgainingReauthenticate. Both are .NET 12 only, and there's noaspnetcore-12.0moniker yet, so gated content would render for nobody.One fix outside the drift: the "locate the Blazor script tag" snippet was missing
@Assets[...], which is wrong in every version.Checked every sample against
release/10.0,release/11.0andmain.Internal previews
Build report