SignalR Security

This commit is contained in:
2025-12-05 23:17:02 +01:00
parent 71c293320b
commit 0c874575d4
2 changed files with 16 additions and 12 deletions

View File

@@ -1,16 +1,15 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
namespace DiunaBI.API.Hubs; namespace DiunaBI.API.Hubs;
/// <summary>
/// SignalR hub for broadcasting entity change notifications to authenticated clients.
/// Clients can only listen - broadcasting is done server-side by EntityChangeInterceptor.
/// </summary>
[Authorize]
public class EntityChangeHub : Hub public class EntityChangeHub : Hub
{ {
public async Task SendEntityChange(string module, string id, string operation) // No public methods - clients can only listen for "EntityChanged" events
{ // Broadcasting is handled server-side by EntityChangeInterceptor via IHubContext
await Clients.All.SendAsync("EntityChanged", new
{
module,
id,
operation
});
}
} }

View File

@@ -37,7 +37,12 @@ builder.Services.AddSingleton<EntityChangeInterceptor>();
builder.Services.AddDbContext<AppDbContext>((serviceProvider, options) => builder.Services.AddDbContext<AppDbContext>((serviceProvider, options) =>
{ {
options.UseSqlServer(connectionString, sqlOptions => sqlOptions.MigrationsAssembly("DiunaBI.Infrastructure")); options.UseSqlServer(connectionString, sqlOptions => sqlOptions.MigrationsAssembly("DiunaBI.Infrastructure"));
options.EnableSensitiveDataLogging();
// Only log SQL parameters in development (may contain sensitive data)
if (builder.Environment.IsDevelopment())
{
options.EnableSensitiveDataLogging();
}
// Add EntityChangeInterceptor // Add EntityChangeInterceptor
var interceptor = serviceProvider.GetRequiredService<EntityChangeInterceptor>(); var interceptor = serviceProvider.GetRequiredService<EntityChangeInterceptor>();
@@ -254,8 +259,8 @@ app.Use(async (context, next) =>
app.MapControllers(); app.MapControllers();
// SignalR Hub // SignalR Hub - Requires JWT authentication
app.MapHub<EntityChangeHub>("/hubs/entitychanges"); app.MapHub<EntityChangeHub>("/hubs/entitychanges").RequireAuthorization();
app.MapGet("/health", () => Results.Ok(new { status = "OK", timestamp = DateTime.UtcNow })) app.MapGet("/health", () => Results.Ok(new { status = "OK", timestamp = DateTime.UtcNow }))
.AllowAnonymous(); .AllowAnonymous();