51 lines
1.6 KiB
C#
51 lines
1.6 KiB
C#
namespace QRRapidoApp.Middleware
|
|
{
|
|
/// <summary>
|
|
/// Adds security headers and JSON error handling for /api/v1/* routes.
|
|
/// </summary>
|
|
public class ApiSecurityHeadersMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly ILogger<ApiSecurityHeadersMiddleware> _logger;
|
|
|
|
public ApiSecurityHeadersMiddleware(RequestDelegate next, ILogger<ApiSecurityHeadersMiddleware> logger)
|
|
{
|
|
_next = next;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
if (!context.Request.Path.StartsWithSegments("/api/v1"))
|
|
{
|
|
await _next(context);
|
|
return;
|
|
}
|
|
|
|
// Security headers for API responses
|
|
context.Response.Headers["X-Content-Type-Options"] = "nosniff";
|
|
context.Response.Headers["X-Frame-Options"] = "DENY";
|
|
|
|
try
|
|
{
|
|
await _next(context);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Unhandled exception on API route {Path}", context.Request.Path);
|
|
|
|
if (!context.Response.HasStarted)
|
|
{
|
|
context.Response.StatusCode = 500;
|
|
context.Response.ContentType = "application/json";
|
|
await context.Response.WriteAsJsonAsync(new
|
|
{
|
|
error = "An internal error occurred. Please try again later.",
|
|
requestId = context.TraceIdentifier
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|