Skip to content

Commit

Permalink
Configure AntiForgery in WebApp
Browse files Browse the repository at this point in the history
  • Loading branch information
raix authored and tjementum committed Jan 16, 2024
1 parent 171e9ed commit 96a519a
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 3 deletions.
2 changes: 2 additions & 0 deletions application/account-management/WebApp/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export declare global {
APPLICATION_VERSION: string;
/* User locale */
LOCALE: string;
/* AntiForgery token */
XSRF_TOKEN: string;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import createClient from "openapi-fetch";
import type { paths } from "./api.generated";

const baseUrl = import.meta.env.PUBLIC_URL;
export const accountManagementApi = createClient<paths>({ baseUrl });
export const accountManagementApi = createClient<paths>({ baseUrl, headers: { "X-XSRF-TOKEN": import.meta.env.XSRF_TOKEN } });
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* AntiForgeryToken Hidden Form Element
*/
export function AntiForgeryToken() {
return (
<input type="hidden" name="__RequestVerificationToken" value={import.meta.env.XSRF_TOKEN} />
);
}
10 changes: 10 additions & 0 deletions application/shared-kernel/ApiCore/ApiCoreConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ public static IServiceCollection AddApiCoreServices(this IServiceCollection serv
options.KnownProxies.Clear();
});

// Enable support for CSRF tokens and configure the header and form field names
services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
options.FormFieldName = "__RequestVerificationToken";
});

builder.AddServiceDefaults();

if (builder.Environment.IsDevelopment())
Expand Down Expand Up @@ -135,6 +142,9 @@ public static WebApplication AddApiCoreConfiguration<TDbContext>(this WebApplica

app.Services.ApplyMigrations<TDbContext>();

// Enable support for CSRF tokens
app.UseAntiforgery();

return app;
}
}
12 changes: 10 additions & 2 deletions application/shared-kernel/ApiCore/Middleware/WebAppMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Security;
using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Json;
Expand All @@ -18,7 +19,9 @@ public sealed class WebAppMiddleware
public const string PublicUrlKey = "PUBLIC_URL";
public const string CdnUrlKey = "CDN_URL";
private const string Locale = "LOCALE";
private const string XsrfToken = "XSRF_TOKEN";
public const string ApplicationVersion = "APPLICATION_VERSION";
private readonly IAntiforgery _antiforgery;

private readonly string _cdnUrl;
private readonly StringValues _contentSecurityPolicy;
Expand All @@ -35,12 +38,14 @@ public WebAppMiddleware(
RequestDelegate next,
Dictionary<string, string> staticRuntimeEnvironment,
string htmlTemplatePath,
IOptions<JsonOptions> jsonOptions
IOptions<JsonOptions> jsonOptions,
IAntiforgery antiforgery
)
{
_next = next;
_staticRuntimeEnvironment = staticRuntimeEnvironment;
_htmlTemplatePath = htmlTemplatePath;
_antiforgery = antiforgery;
_jsonSerializerOptions = jsonOptions.Value.SerializerOptions;

VerifyRuntimeEnvironment(staticRuntimeEnvironment);
Expand Down Expand Up @@ -87,10 +92,13 @@ public Task InvokeAsync(HttpContext context)
{
if (context.Request.Path.ToString().StartsWith("/api/")) return _next(context);

var tokenSet = _antiforgery.GetAndStoreTokens(context);

var cultureFeature = context.Features.Get<IRequestCultureFeature>();
var userCulture = cultureFeature?.RequestCulture.Culture;

var requestEnvironmentVariables = new Dictionary<string, string> { { Locale, userCulture?.Name ?? "en-US" } };
var requestEnvironmentVariables = new Dictionary<string, string>
{ { Locale, userCulture?.Name ?? "en-US" }, { XsrfToken, tokenSet.RequestToken! } };

context.Response.Headers.Append("Content-Security-Policy", _contentSecurityPolicy);
return context.Response.WriteAsync(GetHtmlWithEnvironment(requestEnvironmentVariables));
Expand Down

0 comments on commit 96a519a

Please sign in to comment.