using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.EntityFrameworkCore; using watcher_monitoring.Data; namespace watcher_monitoring.Attributes; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class ApiKeyAuthAttribute : Attribute, IAsyncActionFilter { private const string ApiKeyHeaderName = "X-API-Key"; public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.HttpContext.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey)) { context.Result = new UnauthorizedObjectResult(new { error = "API-Key fehlt im Header" }); return; } var apiKeyString = extractedApiKey.ToString(); var dbContext = context.HttpContext.RequestServices.GetRequiredService(); var logger = context.HttpContext.RequestServices.GetRequiredService>(); var apiKey = await dbContext.ApiKeys .FirstOrDefaultAsync(k => k.Key == apiKeyString); if (apiKey == null) { logger.LogWarning("Ungültiger API-Key verwendet: {ApiKey}", apiKeyString); context.Result = new UnauthorizedObjectResult(new { error = "Ungültiger API-Key" }); return; } if (!apiKey.IsActive) { logger.LogWarning("Inaktiver API-Key verwendet: {Name}", apiKey.Name); context.Result = new UnauthorizedObjectResult(new { error = "API-Key ist deaktiviert" }); return; } if (apiKey.IsExpired) { logger.LogWarning("Abgelaufener API-Key verwendet: {Name}", apiKey.Name); context.Result = new UnauthorizedObjectResult(new { error = "API-Key ist abgelaufen" }); return; } // Letzten Verwendungszeitpunkt aktualisieren apiKey.LastUsedAt = DateTime.UtcNow; await dbContext.SaveChangesAsync(); logger.LogInformation("API-Zugriff mit Key: {Name}", apiKey.Name); await next(); } }