diff --git a/8.0/BlazorWebAssemblyStandaloneWithIdentity/Backend/Program.cs b/8.0/BlazorWebAssemblyStandaloneWithIdentity/Backend/Program.cs index 89672cdf..2d804c92 100644 --- a/8.0/BlazorWebAssemblyStandaloneWithIdentity/Backend/Program.cs +++ b/8.0/BlazorWebAssemblyStandaloneWithIdentity/Backend/Program.cs @@ -1,6 +1,7 @@ using System.Security.Claims; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); @@ -42,13 +43,21 @@ app.MapIdentityApi(); // provide an end point to clear the cookie for logout -// NOTE: This logout code will be updated shortly. -// https://github.com/dotnet/blazor-samples/issues/132 -app.MapPost("/Logout", async (ClaimsPrincipal user, SignInManager signInManager) => +// The request checks for an empty body to prevent CSRF attacks. By requiring something +// in the body, the request must be made from JavaScript, which is the only way to +// access the cookie. It can't be accessed by a form-based post. +// This prevents a malicious site from logging the user out. +// Furthermore, the endpoint is protected by authorization to prevent anonymous access. +// The client simply needs to pass an empty object {} in the body of the request. +app.MapPost("/Logout", async (SignInManager signInManager, [FromBody] object empty) => { - await signInManager.SignOutAsync(); - return TypedResults.Ok(); -}); + if (empty != null) + { + await signInManager.SignOutAsync(); + return Results.Ok(); + } + return Results.Unauthorized(); +}).RequireAuthorization(); // activate the CORS policy app.UseCors("wasm"); diff --git a/8.0/BlazorWebAssemblyStandaloneWithIdentity/BlazorWasmAuth/Identity/CookieAuthenticationStateProvider.cs b/8.0/BlazorWebAssemblyStandaloneWithIdentity/BlazorWasmAuth/Identity/CookieAuthenticationStateProvider.cs index 62bf20ed..3d59bafa 100644 --- a/8.0/BlazorWebAssemblyStandaloneWithIdentity/BlazorWasmAuth/Identity/CookieAuthenticationStateProvider.cs +++ b/8.0/BlazorWebAssemblyStandaloneWithIdentity/BlazorWasmAuth/Identity/CookieAuthenticationStateProvider.cs @@ -3,6 +3,7 @@ using System.Text.Json; using System.Net.Http.Json; using BlazorWasmAuth.Identity.Models; +using System.Text; namespace BlazorWasmAuth.Identity { @@ -201,7 +202,9 @@ public override async Task GetAuthenticationStateAsync() public async Task LogoutAsync() { - await _httpClient.PostAsync("Logout", null); + const string Empty = "{}"; + var emptyContent = new StringContent(Empty, Encoding.UTF8, "application/json"); + await _httpClient.PostAsync("Logout", emptyContent); NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); }