diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs index 96565a6ec3a8..3704516da2eb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs @@ -50,13 +50,16 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn return TypedResults.LocalRedirect($"~/{returnUrl}"); }); - accountGroup.MapPost("/PasskeyCreationOptions", async ( + accountGroup.MapPost("/PasskeyCreationOptions", [RequireAntiforgeryToken] async ( HttpContext context, [FromServices] UserManager userManager, - [FromServices] SignInManager signInManager, - [FromServices] IAntiforgery antiforgery) => + [FromServices] SignInManager signInManager) => { - await antiforgery.ValidateRequestAsync(context); + var antiforgeryValidationFeature = context.Features.Get(); + if (antiforgeryValidationFeature is not { IsValid: true }) + { + return Results.BadRequest(antiforgeryValidationFeature?.Error?.Message ?? "Antiforgery validation failed."); + } var user = await userManager.GetUserAsync(context.User); if (user is null) @@ -75,14 +78,17 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn return TypedResults.Content(optionsJson, contentType: "application/json"); }); - accountGroup.MapPost("/PasskeyRequestOptions", async ( + accountGroup.MapPost("/PasskeyRequestOptions", [RequireAntiforgeryToken] async ( HttpContext context, [FromServices] UserManager userManager, [FromServices] SignInManager signInManager, - [FromServices] IAntiforgery antiforgery, [FromQuery] string? username) => { - await antiforgery.ValidateRequestAsync(context); + var antiforgeryValidationFeature = context.Features.Get(); + if (antiforgeryValidationFeature is not { IsValid: true }) + { + return Results.BadRequest(antiforgeryValidationFeature?.Error?.Message ?? "Antiforgery validation failed."); + } var user = string.IsNullOrEmpty(username) ? null : await userManager.FindByNameAsync(username); var optionsJson = await signInManager.MakePasskeyRequestOptionsAsync(user); @@ -111,11 +117,17 @@ public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEn var loggerFactory = endpoints.ServiceProvider.GetRequiredService(); var downloadLogger = loggerFactory.CreateLogger("DownloadPersonalData"); - manageGroup.MapPost("/DownloadPersonalData", async ( + manageGroup.MapPost("/DownloadPersonalData", [RequireAntiforgeryToken] async ( HttpContext context, [FromServices] UserManager userManager, [FromServices] AuthenticationStateProvider authenticationStateProvider) => { + var antiforgeryValidationFeature = context.Features.Get(); + if (antiforgeryValidationFeature is not { IsValid: true }) + { + return Results.BadRequest(antiforgeryValidationFeature?.Error?.Message ?? "Antiforgery validation failed."); + } + var user = await userManager.GetUserAsync(context.User); if (user is null) { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor index 3a6d501b7d70..2d5c2c23d141 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor @@ -24,7 +24,6 @@
-
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor index 3e46514e0c3f..6dd1765e363f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor @@ -20,7 +20,6 @@
- diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor index 1e14a8d3b604..08ff1e025f76 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor @@ -25,7 +25,6 @@ @if (showRemoveButton) {
-
@@ -48,7 +47,6 @@

Add another service to log in.


-

@foreach (var provider in otherLogins) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index 6caf5d210e61..5ad890989184 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -31,7 +31,6 @@ else

-
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor index 35198ee58d52..f2d98bb53d98 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor @@ -31,7 +31,6 @@ var credentialId = Base64Url.EncodeToString(passkey.CredentialId); }
-
@@ -50,7 +49,6 @@ else } - @if (currentPasskeys is { Count: >= MaxPasskeyCount }) {

You have reached the maximum number of allowed passkeys. Please delete one before adding a new one.

diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor index 65708ecd703c..b43ecbc22120 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor @@ -18,7 +18,6 @@ Deleting this data will permanently remove your account, and this cannot be recovered.

-

diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor index 74542ddb37f8..483cbdfd21f1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor @@ -24,7 +24,6 @@

-
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index 795d01d386cb..c7d56408a358 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -41,7 +41,6 @@ if (isMachineRemembered) {
- } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/ExternalLoginPicker.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/ExternalLoginPicker.razor index ae791f522546..1d459768b8e6 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/ExternalLoginPicker.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/ExternalLoginPicker.razor @@ -18,7 +18,6 @@ else {
-

@foreach (var provider in externalLogins) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor index 756b4c4a6ebf..3fad13f9dad0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor @@ -1,21 +1,11 @@ -@using Microsoft.AspNetCore.Antiforgery -@inject IServiceProvider Services - - + + email-name="@EmailName"> @code { - private AntiforgeryTokenSet? tokens; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - [Parameter] [EditorRequired] public PasskeyOperation Operation { get; set; } @@ -32,9 +22,4 @@ [Parameter(CaptureUnmatchedValues = true)] public IDictionary? AdditionalAttributes { get; set; } - - protected override void OnInitialized() - { - tokens = Services.GetService()?.GetTokens(HttpContext); - } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js index 55a83bcc7ba1..13004de3563d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js @@ -17,10 +17,9 @@ async function fetchWithErrorHandling(url, options = {}) { return response; } -async function createCredential(headers, signal) { +async function createCredential(signal) { const optionsResponse = await fetchWithErrorHandling('/Account/PasskeyCreationOptions', { method: 'POST', - headers, signal, }); const optionsJson = await optionsResponse.json(); @@ -28,10 +27,9 @@ async function createCredential(headers, signal) { return await navigator.credentials.create({ publicKey: options, signal }); } -async function requestCredential(email, mediation, headers, signal) { +async function requestCredential(email, mediation, signal) { const optionsResponse = await fetchWithErrorHandling(`/Account/PasskeyRequestOptions?username=${email}`, { method: 'POST', - headers, signal, }); const optionsJson = await optionsResponse.json(); @@ -48,8 +46,6 @@ customElements.define('passkey-submit', class extends HTMLElement { operation: this.getAttribute('operation'), name: this.getAttribute('name'), emailName: this.getAttribute('email-name'), - requestTokenName: this.getAttribute('request-token-name'), - requestTokenValue: this.getAttribute('request-token-value'), }; this.internals.form.addEventListener('submit', (event) => { @@ -71,16 +67,12 @@ customElements.define('passkey-submit', class extends HTMLElement { throw new Error('Some passkey features are missing. Please update your browser.'); } - const headers = { - [this.attrs.requestTokenName]: this.attrs.requestTokenValue, - }; - if (this.attrs.operation === 'Create') { - return await createCredential(headers, signal); + return await createCredential(signal); } else if (this.attrs.operation === 'Request') { const email = new FormData(this.internals.form).get(this.attrs.emailName); const mediation = useConditionalMediation ? 'conditional' : undefined; - return await requestCredential(email, mediation, headers, signal); + return await requestCredential(email, mediation, signal); } else { throw new Error(`Unknown passkey operation '${this.attrs.operation}'.`); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Layout/NavMenu.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Layout/NavMenu.razor index b6dca050dfb1..46e4689ab135 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Layout/NavMenu.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Layout/NavMenu.razor @@ -56,7 +56,6 @@