From 362dee0c83ef71ecc0062b8af1b69c57882bfa07 Mon Sep 17 00:00:00 2001 From: daniel-hbn Date: Tue, 17 Jun 2025 19:29:41 +0200 Subject: [PATCH] Login Logik aktualisiert --- Watcher/Controllers/AuthController.cs | 75 ++++----------- Watcher/Program.cs | 127 ++++++++++++++------------ Watcher/Views/Auth/Login.cshtml | 48 ++++------ Watcher/Views/Shared/_Layout.cshtml | 4 +- Watcher/appsettings.json | 1 + 5 files changed, 109 insertions(+), 146 deletions(-) diff --git a/Watcher/Controllers/AuthController.cs b/Watcher/Controllers/AuthController.cs index 029ea39..2394675 100644 --- a/Watcher/Controllers/AuthController.cs +++ b/Watcher/Controllers/AuthController.cs @@ -1,80 +1,39 @@ -using System.Security.Claims; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using Watcher.ViewModels; namespace Watcher.Controllers; public class AuthController : Controller { - private readonly IConfiguration _config; - - public AuthController(IConfiguration config) + public IActionResult Login() { - _config = config; + return View(); } - [HttpGet] - public IActionResult Login(string? returnUrl = null) + public IActionResult SignIn() { - var vm = new LoginViewModel { ReturnUrl = returnUrl }; - return View(vm); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Login(LoginViewModel model) - { - if (!ModelState.IsValid) - return View(model); - - // Beispielhafte, harte lokale Benutzerprüfung - if (model.Username == "admin" && model.Password == "password") - { - var claims = new List - { - new Claim(ClaimTypes.Name, model.Username), - new Claim(ClaimTypes.Role, "Admin") - }; - - var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); - var principal = new ClaimsPrincipal(identity); - - await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); - - return Redirect(model.ReturnUrl ?? "/"); - } - - ModelState.AddModelError("", "Ungültiger Benutzername oder Passwort"); - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public IActionResult SignIn(string? returnUrl = null) - { - var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Auth", new { returnUrl }); return Challenge(new AuthenticationProperties { - RedirectUri = redirectUrl + RedirectUri = "/" }, "oidc"); } - [HttpGet] - public IActionResult ExternalLoginCallback(string? returnUrl = null) - { - return Redirect(returnUrl ?? "/"); - } - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Logout() +[ValidateAntiForgeryToken] +public async Task Logout() +{ + // Lokales Cookie löschen + await HttpContext.SignOutAsync("Cookies"); + + // Externes OIDC-Logout initiieren + await HttpContext.SignOutAsync("oidc", new AuthenticationProperties { - await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - return RedirectToAction("Index", "Home"); - } + RedirectUri = "/" // Nach Logout zurück zur Startseite oder Login-Seite + }); + + return RedirectToAction("Index", "Home"); +} [Authorize] public IActionResult Info() diff --git a/Watcher/Program.cs b/Watcher/Program.cs index b52331a..9fd427a 100644 --- a/Watcher/Program.cs +++ b/Watcher/Program.cs @@ -55,67 +55,78 @@ builder.Services.AddDbContext((serviceProvider, options) => builder.Services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; - options.DefaultChallengeScheme = "oidc"; + options.DefaultChallengeScheme = "Cookies"; // Nur wenn kein OIDC erzwungen wird }) -.AddCookie("Cookies") -.AddOpenIdConnect("oidc", options => +.AddCookie("Cookies", options => { - var config = builder.Configuration.GetSection("Authentication:PocketID"); - options.Authority = config["Authority"]; - options.ClientId = config["ClientId"]; - options.ClientSecret = config["ClientSecret"]; - options.ResponseType = "code"; - options.CallbackPath = config["CallbackPath"]; - options.SaveTokens = true; - - options.GetClaimsFromUserInfoEndpoint = true; - - options.Scope.Clear(); - options.Scope.Add("openid"); - options.Scope.Add("profile"); - options.Scope.Add("email"); - - options.Events = new OpenIdConnectEvents -{ - OnTokenValidated = async ctx => - { - var db = ctx.HttpContext.RequestServices.GetRequiredService(); - - var principal = ctx.Principal; - var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; - var preferredUsername = principal.FindFirst("preferred_username")?.Value; - var email = principal.FindFirst("email")?.Value; - - if (string.IsNullOrEmpty(pocketId)) - return; - - var user = await db.Users.FirstOrDefaultAsync(u => u.PocketId == pocketId); - - if (user == null) - { - user = new User - { - PocketId = pocketId, - PreferredUsername = preferredUsername ?? "", - Email = email, - LastLogin = DateTime.UtcNow - }; - db.Users.Add(user); - } - else - { - user.LastLogin = DateTime.UtcNow; - user.PreferredUsername = preferredUsername ?? user.PreferredUsername; - user.Email = email ?? user.Email; - db.Users.Update(user); - } - - await db.SaveChangesAsync(); - } -}; - + options.LoginPath = "/Account/Login"; // Falls eigene Login-Seite }); +// PocketID nur konfigurieren, wenn aktiviert +var pocketIdSection = builder.Configuration.GetSection("Authentication:PocketID"); +var pocketIdEnabled = pocketIdSection.GetValue("Enabled"); + +if (pocketIdEnabled) +{ + builder.Services.AddAuthentication() + .AddOpenIdConnect("oidc", options => + { + options.Authority = pocketIdSection["Authority"]; + options.ClientId = pocketIdSection["ClientId"]; + options.ClientSecret = pocketIdSection["ClientSecret"]; + options.ResponseType = "code"; + options.CallbackPath = pocketIdSection["CallbackPath"]; + options.SaveTokens = true; + + options.GetClaimsFromUserInfoEndpoint = true; + + options.Scope.Clear(); + options.Scope.Add("openid"); + options.Scope.Add("profile"); + options.Scope.Add("email"); + + options.Events = new OpenIdConnectEvents + { + OnTokenValidated = async ctx => + { + var db = ctx.HttpContext.RequestServices.GetRequiredService(); + + var principal = ctx.Principal; + var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; + var preferredUsername = principal.FindFirst("preferred_username")?.Value; + var email = principal.FindFirst("email")?.Value; + + if (string.IsNullOrEmpty(pocketId)) + return; + + var user = await db.Users.FirstOrDefaultAsync(u => u.PocketId == pocketId); + + if (user == null) + { + user = new User + { + PocketId = pocketId, + PreferredUsername = preferredUsername ?? "", + Email = email, + LastLogin = DateTime.UtcNow + }; + db.Users.Add(user); + } + else + { + user.LastLogin = DateTime.UtcNow; + user.PreferredUsername = preferredUsername ?? user.PreferredUsername; + user.Email = email ?? user.Email; + db.Users.Update(user); + } + + await db.SaveChangesAsync(); + } + }; + }); +} + + var app = builder.Build(); @@ -145,7 +156,7 @@ app.UseStaticFiles(); app.MapControllerRoute( name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}" + pattern: "{controller=Auth}/{action=Login}/" ); diff --git a/Watcher/Views/Auth/Login.cshtml b/Watcher/Views/Auth/Login.cshtml index 38cdbc4..4a5e8e1 100644 --- a/Watcher/Views/Auth/Login.cshtml +++ b/Watcher/Views/Auth/Login.cshtml @@ -1,36 +1,28 @@ @model Watcher.ViewModels.LoginViewModel - @{ ViewData["Title"] = "Login"; } -

Anmelden

+ diff --git a/Watcher/Views/Shared/_Layout.cshtml b/Watcher/Views/Shared/_Layout.cshtml index 9104883..2ccc018 100644 --- a/Watcher/Views/Shared/_Layout.cshtml +++ b/Watcher/Views/Shared/_Layout.cshtml @@ -62,10 +62,10 @@

Watcher