-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
When using the AntiforgeryStateProvider
class added #49108, it always returns null from GetAntiforgeryToken()
on the Blazor Wasm side, after pre-rendering. I'm trying to use the token returned from this class to call an API controller that is annotated with [ValidateAntiForgeryToken]
.
Expected Behavior
GetAntiforgeryToken()
should return a non null token.
Steps To Reproduce
In your Blazor page, Test.razor
:
@inject AntiforgeryStateProvider Antiforgery
<button @onclick="GetAntiforgery">Get Antiforgery</button>
<pre>
@mDebug
</pre>
@code {
private string? mDebug;
private void GetAntiforgery()
{
mDebug = "Token: " + Antiforgery.GetAntiforgeryToken()?.Value;
}
}
In your .cshtml
file that displays the pre-rendered component:
<component type="typeof(Test)" render-mode="WebAssemblyPrerendered" />
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
<persist-component-state />
When you click the "Get Antiforgery" button, I would expect to see "Token: " followed by random digits. But was I actually see is just "Token: ".
Exceptions (if any)
N/A
.NET Version
8.0.100-rc.1.23463.5
Anything else?
The two relevant classes are:
DefaultAntiforgeryStateProvider
- the implementation of theAntiforgeryStateProvider
on the client side.EndpointAntiforgeryStateProvider
- a subclassDefaultAntiforgeryStateProvider
that is used on the server side during pre-rendering.
It looks like the problem is DefaultAntiforgeryStateProvider
only reads a value from PersistentComponentState
in the constructor. _currentToken
is readonly, so it is not possible for it get set in another way. EndpointAntiforgeryStateProvider
is the only subclass of DefaultAntiforgeryStateProvider
, but it has no way to communicate its token to its base class to be persisted.
When I change DefaultAntiforgeryStateProvider
to call the virtual GetAntiforgeryToken()
method to get the token to persist, the problem goes away, i.e. GetAntiforgeryToken()
starts returning a non null token on the WebAssembly side:
Note that this only fixes components in render-mode="WebAssemblyPrerendered"
. I'm not sure how DefaultAntiforgeryStateProvider
is supposed to work in render-mode="WebAssembly"
, as I don't think PersistentComponentState
works in there.
In case it's helpful, here is the commit from my application where I use antiforgery: AustinWise/DinnerKillPoints@b8e4eff