Added Authentication with user-auth and apikey-auth
All checks were successful
Gitea CI/CD / dotnet-build-and-test (push) Successful in 10m5s
Gitea CI/CD / Set Tag Name (push) Successful in 5s
Gitea CI/CD / docker-build-and-push (push) Successful in 11m28s
Gitea CI/CD / Create Tag (push) Successful in 5s

This commit is contained in:
2026-01-09 10:18:06 +01:00
parent 05e5a209da
commit d8b164e3eb
25 changed files with 1809 additions and 5 deletions

View File

@@ -0,0 +1,133 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using watcher_monitoring.Data;
using watcher_monitoring.Models;
namespace watcher_monitoring.Controllers;
public class AuthController : Controller
{
private readonly WatcherDbContext _context;
private readonly ILogger<AuthController> _logger;
public AuthController(WatcherDbContext context, ILogger<AuthController> logger)
{
_context = context;
_logger = logger;
}
[AllowAnonymous]
[HttpGet]
public IActionResult Login(string? returnUrl = null)
{
// Wenn der Benutzer bereits angemeldet ist, zur Startseite weiterleiten
if (User.Identity?.IsAuthenticated == true)
{
return RedirectToAction("Index", "Home");
}
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string? returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (!ModelState.IsValid)
{
return View(model);
}
try
{
// Benutzer suchen
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Username == model.Username && u.IsActive);
if (user == null)
{
_logger.LogWarning("Login-Versuch mit ungültigem Benutzernamen: {Username}", model.Username);
TempData["Error"] = "Ungültiger Benutzername oder Passwort";
return View(model);
}
// Passwort überprüfen (BCrypt)
if (!BCrypt.Net.BCrypt.Verify(model.Password, user.Password))
{
_logger.LogWarning("Login-Versuch mit falschem Passwort für Benutzer: {Username}", model.Username);
TempData["Error"] = "Ungültiger Benutzername oder Passwort";
return View(model);
}
// LastLogin aktualisieren
user.LastLogin = DateTime.UtcNow;
await _context.SaveChangesAsync();
// Claims erstellen
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.Email, user.Email),
new Claim("LastLogin", user.LastLogin.ToString("o"))
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
var authProperties = new AuthenticationProperties
{
IsPersistent = model.RememberMe,
ExpiresUtc = model.RememberMe ? DateTimeOffset.UtcNow.AddDays(30) : DateTimeOffset.UtcNow.AddHours(8)
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
claimsPrincipal,
authProperties);
_logger.LogInformation("Benutzer {Username} erfolgreich angemeldet", user.Username);
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
_logger.LogError(ex, "Fehler beim Login-Vorgang");
TempData["Error"] = "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.";
return View(model);
}
}
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
var username = User.Identity?.Name ?? "Unbekannt";
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
_logger.LogInformation("Benutzer {Username} erfolgreich abgemeldet", username);
return RedirectToAction("Login", "Auth");
}
[AllowAnonymous]
public IActionResult AccessDenied()
{
return View();
}
}