Skip to content

AntiforgeryStateProvider always returns a null token in WebAssemblyPrerendered mode #50900

@AustinWise

Description

@AustinWise

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:

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:

AustinWise@63e9553

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

Metadata

Metadata

Assignees

Labels

area-blazorIncludes: Blazor, Razor ComponentsbugThis issue describes a behavior which is not expected - a bug.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions