-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
dot net version: NET 10.0.100-rc.1.25451.107
application: blazor (unified)
I'm currently getting 400 Bad Request errors when trying to connect to my SignalR hubs that have been setup with default authorization in my Program.cs. After I have applied the RequireAuthorization() method via the HubEndpointConventionBuilder when mapping my endpoints, I start to receive 400 Bad Request errors when calling StartAsync on my HubConnectionBuilder within my razor view.
I looked at Fiddler to see why the request had failed, and it said the following:
A valid antiforgery token was not provided with the request. Add an antiforgery token, or disable antiforgery validation for this endpoint.

Why would you need an anti-forgery token for establishing a connection to a SignalR hub?
I attempted to disable the antiforgery token validation for my SignalR hubs, but no matter what I try I am greeted with the same error.
When I remove the RequireAuthorization() call in my Program.cs, I am able to connect with no issues. I'm confused as to how anti forgery tokens are tied to authentication flow for SignalR.
My Program.cs:
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using ogd.Components;
using ogd.Components.Account;
using ogd.Data;
using ogd.Data.Clients;
using ogd.Data.Hubs;
using ogd.Data.Repositories;
using ogd.Data.Repositories.Interfaces;
using ogd.Hubs;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped();
builder.Services.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>();
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Stores.SchemaVersion = IdentitySchemaVersions.Version3;
})
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
builder.Services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.Lax; // important
options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // HTTPS only
});
// Email sender (placeholder)
builder.Services.AddSingleton<IEmailSender, IdentityNoOpEmailSender>();
// Logging
builder.Logging.AddConsole();
builder.Logging.AddDebug();
builder.Services.AddHttpClient();
builder.Services.Configure(options =>
{
options.ValidationInterval = TimeSpan.FromSeconds(10); // consider implication of lots of users
});
builder.Services.AddScoped<IAlertsRepository, AlertsRepository>();
builder.Services.AddScoped<IForumThreadsRepository, ForumThreadsRepository>();
builder.Services.AddScoped<IUsersRepository, UsersRepository>();
builder.Services.AddScoped<IPlatformsRepository, PlatformsRepository>();
builder.Services.AddSingleton();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
// Map SignalR hubs first, and disable antiforgery just for those
var hubs = app.MapGroup("/hubs").DisableAntiforgery();
hubs.MapHub("/alertshub").RequireAuthorization();
hubs.MapHub("/forumthreadshub").RequireAuthorization();
hubs.MapHub("/usershub").RequireAuthorization();
hubs.MapHub("/irchub"); // no auth
app.MapStaticAssets();
app.MapRazorComponents()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(ogd.Client._Imports).Assembly);
app.MapAdditionalIdentityEndpoints();
// seed roles + admin user
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
await DatabaseSeeder.SeedIdentityAsync(services);
}
app.Run();
Expected Behavior
I should expect to get a 200 OK response back from the /negotiate HTTP call to my SignalR hub indicating a successfully established connection
Steps To Reproduce
Adding default authorization to SignalR hubs and then attempting to connect via StartAsync() within a razor view.
Exceptions (if any)
A valid antiforgery token was not provided with the request. Add an antiforgery token, or disable antiforgery validation for this endpoint.
.NET Version
NET 10.0.100-rc.1.25451.107
Anything else?
No response