Minimal API incorrectly returns 400 with antiforgery error message
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
I have a Blazor web app on net10.
My `Program.cs` has a pretty common setup:
```cs
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel( opt => opt.AddServerHeader = false );
builder.Services
.AddAntiforgery()
.AddMyCustomServices()
.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
app.UseStatusCodePagesWithReExecute( "/status-{0}", createScopeForStatusCodePages: true );
app.UseHttpsRedirection();
app.UseRequestLocalization();
app.UseAntiforgery();
app.MapStaticAssets();
// We will write custom CSP headers with app.Use() below
app.MapRazorComponents()
.AddInteractiveServerRenderMode( opt => opt.ContentSecurityFrameAncestorsPolicy = null )
.AddAdditionalAssemblies( typeof( MyFallbackPage ).Assembly );
app.Use( AddCustomCspHeaders );
app.MapCustomMinimalApis();
await app.RunAsync();
```
The "MapCustomMinimalApis" registers various routes to be handled as API routes or intercepts that I don't want Blazor to handle. The one that's giving me the issue is a webhook callback.
```cs
app.MapPost( "/api/webhooks/callback", ProcessWebhook )
.DisableAntiforgery().ShortCircuit();
```
A complication is that `MyFallbackPage` is a Blazor page with the route `@page "/{*RequestPath}"` - it's a fallback that should receive all requests that aren't APIs, static assets or other registered pages.
This setup works perfectly... for the most part.
If I execute this webhook from Postman it behaves exactly as expected, however when the webhook is called from a 3rd party service I always get a 400 response with the body text:
`A valid antiforgery token was not provided with the request. Add an antiforgery token, or disable antiforgery validation for this endpoint.`
The only material differences between the Postman request that works, and the actual webhook callback that doesn't are:
- Failed request has no "Accept" header
- Failed request has no "Accept-Encoding" headers
- Failed request has no "Cache-Control" headers
- Failed request has no "Cookie" headers
- Failed request has multiple "User-Agent" headers
At present I am running through a Dev Tunnel, so it's not clear to me whether the tunnel is contributing, but I suspect not.
No breakpoints in my code get hit in the 400 condition.
The response 400 error includes the header "blazor-enhanced-nav: allow" which makes me think the request is being routed to the Blazor fallback page rather than being picked up by the Minimal API route, but I don't understand why or how to account for this missing header, if that indeed is the issue.
### Expected Behavior
"Accept" header should not influence routing to mapped handlers.
### Steps To Reproduce
_No response_
### Exceptions (if any)
_No response_
### .NET Version
10.0.201
### Anything else?
```text
.NET SDK:
Version: 10.0.201
Commit: 4d3023de60
Workload version: 10.0.200-manifests.121cc9e6
MSBuild version: 18.3.0-release-26153-122+4d3023de6
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\10.0.201\
.NET workloads installed:
[android]
Installation Source: VS 18.4.11626.88
Manifest Version: 36.1.30/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.android\36.1.30\WorkloadManifest.json
Install Type: Msi
[wasm-tools]
Installation Source: VS 18.4.11626.88
Manifest Version: 10.0.105/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.workload.mono.toolchain.current\10.0.105\WorkloadManifest.json
Install Type: Msi
[maui-windows]
Installation Source: VS 18.4.11626.88
Manifest Version: 10.0.20/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maui\10.0.20\WorkloadManifest.json
Install Type: Msi
[maccatalyst]
Installation Source: VS 18.4.11626.88
Manifest Version: 26.2.10217/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maccatalyst\26.2.10217\WorkloadManifest.json
Install Type: Msi
[ios]
Installation Source: VS 18.4.11626.88
Manifest Version: 26.2.10217/10.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.ios\26.2.10217\WorkloadManifest.json
Install Type: Msi
Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.
Host:
Version: 10.0.5
Architecture: x64
Commit: a612c2a105
.NET SDKs installed:
9.0.115 [C:\Program Files\dotnet\sdk]
10.0.100-preview.7.25380.108 [C:\Program Files\dotnet\sdk]
10.0.100-rc.1.25451.107 [C:\Program Files\dotnet\sdk]
10.0.201 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 8.0.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 10.0.0-preview.7.25380.108 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 10.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 10.0.0-preview.7.25380.108 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 10.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 8.0.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 10.0.0-preview.7.25380.108 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 10.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
```
Contributor guide
Assessment
This issue has not been assessed yet.