From 6cc42a6ef9c0a3b52ea30a02927342b4f2002d55 Mon Sep 17 00:00:00 2001 From: rameel Date: Sun, 30 Aug 2026 12:59:08 +0500 Subject: [PATCH] Enable antiforgery token metadata by default --- README.md | 20 ++++++++++++++----- .../HtmxToolkitOptions.cs | 3 ++- .../HtmxConfigTagHelperTests.cs | 11 ++++++---- .../HtmxToolkitOptionsTests.cs | 2 +- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7bfc87c..f099fb6 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,6 @@ Register the toolkit and select the HTMX version used by the application: ```csharp builder.Services.AddHtmxToolkit(options => { - options.IncludeAntiforgeryToken = true; options.UseHtmxV2(config => { config.DefaultSwapStyle = HtmxSwap.OuterHtml; @@ -660,7 +659,6 @@ The version-specific callback exposes only settings supported by the selected HT ```csharp builder.Services.AddHtmxToolkit(options => { - options.IncludeAntiforgeryToken = true; options.UseHtmxV2(config => { config.DefaultSwapStyle = HtmxSwap.OuterHtml; @@ -756,9 +754,21 @@ responses, configure `NoSwap` as shown in the HTMX 4.x example above. ## Toolkit Script The toolkit script provides antiforgery support and HTMX compatibility behavior. -If you have enabled **Antiforgery** token generation in the configuration -(`IncludeAntiforgeryToken = true`), include it to ensure the token is present in form -parameters or headers and refreshed in a timely manner. +Antiforgery metadata generation is enabled by default. Include the script to ensure the +token is added to non-GET request form parameters or headers and refreshed in a timely manner. + +Sending the token does not enable server-side validation by itself. Configure antiforgery +validation for the corresponding ASP.NET Core endpoints as appropriate. + +To disable antiforgery metadata generation—for example, when the application handles +antiforgery separately or does not issue unsafe HTMX requests—set the option to `false`: + +```csharp +builder.Services.AddHtmxToolkit(options => +{ + options.IncludeAntiforgeryToken = false; +}); +``` To do this, you can directly include the contents of the script file on the page: diff --git a/src/Ramstack.HtmxToolkit/HtmxToolkitOptions.cs b/src/Ramstack.HtmxToolkit/HtmxToolkitOptions.cs index c8260cd..a37c98d 100644 --- a/src/Ramstack.HtmxToolkit/HtmxToolkitOptions.cs +++ b/src/Ramstack.HtmxToolkit/HtmxToolkitOptions.cs @@ -29,8 +29,9 @@ public HtmxConfig HtmxConfig /// /// Gets or sets a value indicating whether antiforgery request metadata is rendered by the configuration tag helper. + /// Defaults to . /// - public bool IncludeAntiforgeryToken { get; set; } + public bool IncludeAntiforgeryToken { get; set; } = true; /// /// Gets the HTMX major version used for version-sensitive generated markup. diff --git a/tests/Ramstack.HtmxToolkit.Tests/HtmxConfigTagHelperTests.cs b/tests/Ramstack.HtmxToolkit.Tests/HtmxConfigTagHelperTests.cs index 3182715..da22898 100644 --- a/tests/Ramstack.HtmxToolkit.Tests/HtmxConfigTagHelperTests.cs +++ b/tests/Ramstack.HtmxToolkit.Tests/HtmxConfigTagHelperTests.cs @@ -313,11 +313,11 @@ public async Task ProcessAsync_EscapesHtmlSensitiveCharacters() } [Test] - public async Task ProcessAsync_IncludeAntiforgeryToken_RendersDataAttributes() + public async Task ProcessAsync_AntiforgeryEnabledByDefault_RendersDataAttributes() { var antiforgery = new StubAntiforgery(); var httpContext = new DefaultHttpContext(); - var options = new HtmxToolkitOptions { IncludeAntiforgeryToken = true }; + var options = new HtmxToolkitOptions(); var helper = CreateHelper(options, antiforgery); helper.ViewContext = new ViewContext { HttpContext = httpContext }; @@ -341,7 +341,7 @@ public async Task ProcessAsync_AntiforgeryDisabled_DoesNotRequestOrRenderTokens( var antiforgery = new StubAntiforgery(); var output = TestHelper.CreateTagHelperOutput(); - await CreateHelper(new HtmxToolkitOptions(), antiforgery) + await CreateHelper(new HtmxToolkitOptions { IncludeAntiforgeryToken = false }, antiforgery) .ProcessAsync(TestHelper.CreateTagHelperContext(), output); Assert.Multiple(() => @@ -362,7 +362,10 @@ await CreateHelper(new HtmxToolkitOptions(), antiforgery) } private static HtmxConfigTagHelper CreateHelper(HtmxToolkitOptions options, IAntiforgery? antiforgery = null) => - new(antiforgery ?? new StubAntiforgery(), Options.Create(options)); + new(antiforgery ?? new StubAntiforgery(), Options.Create(options)) + { + ViewContext = new ViewContext { HttpContext = new DefaultHttpContext() } + }; private static string GetContent(TagHelperOutput output) => output.Attributes["content"]!.Value!.ToString()!; diff --git a/tests/Ramstack.HtmxToolkit.Tests/HtmxToolkitOptionsTests.cs b/tests/Ramstack.HtmxToolkit.Tests/HtmxToolkitOptionsTests.cs index 36a9893..1a11d62 100644 --- a/tests/Ramstack.HtmxToolkit.Tests/HtmxToolkitOptionsTests.cs +++ b/tests/Ramstack.HtmxToolkit.Tests/HtmxToolkitOptionsTests.cs @@ -147,7 +147,7 @@ public void AddHtmxToolkit_WithoutConfiguration_ExposesDefaultOptions() { Assert.That(options.TargetVersion, Is.EqualTo(HtmxTargetVersion.V2)); Assert.That(options.HtmxConfig, Is.TypeOf()); - Assert.That(options.IncludeAntiforgeryToken, Is.False); + Assert.That(options.IncludeAntiforgeryToken, Is.True); }); } }