diff --git a/app/backend/Program.cs b/app/backend/Program.cs index 999eac94..19759448 100644 --- a/app/backend/Program.cs +++ b/app/backend/Program.cs @@ -1,5 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. +using Microsoft.AspNetCore.Antiforgery; + var builder = WebApplication.CreateBuilder(args); builder.Configuration.ConfigureAzureKeyVault(); @@ -12,6 +14,7 @@ builder.Services.AddRazorPages(); builder.Services.AddCrossOriginResourceSharing(); builder.Services.AddAzureServices(); +builder.Services.AddAntiforgery(options => { options.HeaderName = "X-CSRF-TOKEN-HEADER"; options.FormFieldName = "X-CSRF-TOKEN-FORM"; }); if (builder.Environment.IsDevelopment()) { @@ -80,8 +83,17 @@ app.UseStaticFiles(); app.UseCors(); app.UseBlazorFrameworkFiles(); +app.UseAntiforgery(); app.MapRazorPages(); app.MapControllers(); + +app.Use(next => context => +{ + var antiforgery = app.Services.GetRequiredService(); + var tokens = antiforgery.GetAndStoreTokens(context); + context.Response.Cookies.Append("XSRF-TOKEN", tokens?.RequestToken ?? string.Empty, new CookieOptions() { HttpOnly = false }); + return next(context); +}); app.MapFallbackToFile("index.html"); app.MapApi(); diff --git a/app/frontend/Pages/Docs.razor.cs b/app/frontend/Pages/Docs.razor.cs index 4d3d0083..a33cc18b 100644 --- a/app/frontend/Pages/Docs.razor.cs +++ b/app/frontend/Pages/Docs.razor.cs @@ -28,6 +28,9 @@ public sealed partial class Docs : IDisposable [Inject] public required ILogger Logger { get; set; } + [Inject] + public required IJSRuntime JSRuntime { get; set; } + private bool FilesSelected => _fileUpload is { Files.Count: > 0 }; protected override void OnInitialized() => @@ -64,8 +67,10 @@ private async Task SubmitFilesForUploadAsync() { if (_fileUpload is { Files.Count: > 0 }) { + var cookie = await JSRuntime.InvokeAsync("getCookie", "XSRF-TOKEN"); + var result = await Client.UploadDocumentsAsync( - _fileUpload.Files, MaxIndividualFileSize); + _fileUpload.Files, MaxIndividualFileSize, cookie); Logger.LogInformation("Result: {x}", result); diff --git a/app/frontend/Services/ApiClient.cs b/app/frontend/Services/ApiClient.cs index 4622cfeb..89af8703 100644 --- a/app/frontend/Services/ApiClient.cs +++ b/app/frontend/Services/ApiClient.cs @@ -26,7 +26,8 @@ public async Task ShowLogoutButtonAsync() public async Task UploadDocumentsAsync( IReadOnlyList files, - long maxAllowedSize) + long maxAllowedSize, + string cookie) { try { @@ -42,6 +43,10 @@ public async Task UploadDocumentsAsync( content.Add(fileContent, file.Name, file.Name); } + // set cookie + content.Headers.Add("X-CSRF-TOKEN-FORM", cookie); + content.Headers.Add("X-CSRF-TOKEN-HEADER", cookie); + var response = await httpClient.PostAsync("api/documents", content); response.EnsureSuccessStatusCode(); diff --git a/app/frontend/wwwroot/getCookie.js b/app/frontend/wwwroot/getCookie.js new file mode 100644 index 00000000..7bfc7410 --- /dev/null +++ b/app/frontend/wwwroot/getCookie.js @@ -0,0 +1,10 @@ +function getCookie(cname) { + var decodedCookie = decodeURIComponent(document.cookie); + var ca = decodedCookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var arr = ca[i].split('='); + if (arr[0] == cname) + return arr[1] + } + return ""; +} \ No newline at end of file diff --git a/app/frontend/wwwroot/index.html b/app/frontend/wwwroot/index.html index 3d5951ff..9f48d4b9 100644 --- a/app/frontend/wwwroot/index.html +++ b/app/frontend/wwwroot/index.html @@ -35,6 +35,7 @@ +