Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add antiforgery token to forms rendered interactively on the server
Browse files Browse the repository at this point in the history
halter73 committed Oct 5, 2023
1 parent 48ccec8 commit 425bd12
Showing 6 changed files with 56 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ internal void SetRequestContext(HttpContext context)
{
if (_context == null)
{
return null;
// We're in an interactive context. Use the token persisted during static rendering.
return base.GetAntiforgeryToken();
}

// We already have a callback setup to generate the token when the response starts if needed.
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ public DefaultAntiforgeryStateProvider(PersistentComponentState state)
{
state.PersistAsJson(PersistenceKey, GetAntiforgeryToken());
return Task.CompletedTask;
}, RenderMode.InteractiveWebAssembly);
}, RenderMode.InteractiveAuto);

state.TryTakeFromJson(PersistenceKey, out _currentToken);
}
Original file line number Diff line number Diff line change
@@ -909,6 +909,21 @@ public void CanUseAntiforgeryTokenInWasm()
DispatchToFormCore(dispatchToForm);
}

[Fact]
public void CanUseAntiforgeryTokenWithServerInteractivity()
{
var dispatchToForm = new DispatchToForm(this)
{
Url = "forms/antiforgery-server-interactive",
FormCssSelector = "form",
InputFieldId = "value",
InputFieldValue = "stranger",
SuppressEnhancedNavigation = true,
Ready = "really-ready",
};
DispatchToFormCore(dispatchToForm);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
using Components.TestServer.RazorComponents;
using Components.TestServer.RazorComponents.Pages.Forms;
using Components.TestServer.Services;
using Microsoft.AspNetCore.Components.WebAssembly.Server;
using Microsoft.AspNetCore.Mvc;

namespace TestServer;
@@ -73,6 +72,19 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
InteractiveStreamingRenderingComponent.MapEndpoints(endpoints);

MapEnhancedNavigationEndpoints(endpoints);

endpoints.MapPost("/verify-antiforgery", (
[FromForm] string value,
[FromForm(Name = "__RequestVerificationToken")] string csrfToken) =>
{
// We shouldn't get this far without a valid CSRF token, but we double check it's there.
if (string.IsNullOrEmpty(csrfToken))
{
throw new Exception("Invalid POST to /verify-antiforgery!");
}

return TypedResults.Text($"<p id='pass'>Hello {value}!</p>", "text/html");
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@page "/forms/antiforgery-server-interactive"

@using Microsoft.AspNetCore.Components.Forms

@attribute [RenderModeInteractiveServer]

<h3>FormRenderedWithServerInteractivityCanUseAntiforgeryToken</h3>

<form action="verify-antiforgery" method="post" @formname="verify-antiforgery">
<AntiforgeryToken />
<input type="text" id="value" name="value" />
<input id="send" name="send" type="submit" value="Send" />
</form>

@if (HttpContext is null)
{
<p id="really-ready">Interactively rendered!</p>
}

@code {
[CascadingParameter]
HttpContext? HttpContext { get; set; }
}
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
{
@if (_succeeded)
{
<p id="pass">Posting the value succeded.</p>
<p id="pass">Posting the value succeeded.</p>
}
else
{
@@ -42,7 +42,7 @@ else
if (OperatingSystem.IsBrowser())
{
var antiforgery = AntiforgeryState.GetAntiforgeryToken();
_token = antiforgery.Value;
_token = antiforgery.Value;
}
}

0 comments on commit 425bd12

Please sign in to comment.