diff --git a/Components/Pages/Books.razor b/Components/Pages/Books.razor index 46e9590..795cac9 100644 --- a/Components/Pages/Books.razor +++ b/Components/Pages/Books.razor @@ -1,4 +1,5 @@ @page "/books" +@attribute [Microsoft.AspNetCore.Authorization.Authorize] @using SecDevOpsLab.Models @using SecDevOpsLab.Data @inject AppDbContext Db diff --git a/Components/Pages/Login.razor b/Components/Pages/Login.razor new file mode 100644 index 0000000..fc10951 --- /dev/null +++ b/Components/Pages/Login.razor @@ -0,0 +1,39 @@ +@page "/login" +@using System.Security.Claims +@using Microsoft.AspNetCore.Authentication +@using Microsoft.AspNetCore.Authentication.Cookies +@inject NavigationManager Navigation + +

SecDevOps Lab Login

+ +@if (!string.IsNullOrEmpty(errorMessage)) +{ +
@errorMessage
+} + +@* Wichtig: Ein traditionelles HTML-Formular nutzen, um Cookies setzen zu können *@ +
+
+ + +
+
+ + +
+ +
+ +@code { + private string? errorMessage; + + protected override void OnInitialized() + { + // Falls ein Fehler beim Login auftrat, fangen wir ihn über die URL ab + var uri = Navigation.ToAbsoluteUri(Navigation.Uri); + if (Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query).TryGetValue("error", out var error)) + { + errorMessage = "Ungültige Zugangsdaten."; + } + } +} diff --git a/Program.cs b/Program.cs index 24f080b..9cced66 100644 --- a/Program.cs +++ b/Program.cs @@ -3,10 +3,29 @@ using Microsoft.EntityFrameworkCore; // Importieren der Klassen using SecDevOpsLab.Data; using SecDevOpsLab.Components; +// NEU: Namespaces für Authentifizierung und Routing hinzufügen +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Server; +using System.Security.Claims; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; // Initialisieren des Web Builders, der den Server und die Umgebung vorbereitet var builder = WebApplication.CreateBuilder(args); +// NEU: Blazor-Authentifizierungsdienste registrieren +builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) + .AddCookie(options => + { + options.LoginPath = "/login"; // Wohin unberechtigte Nutzer geleitet werden + options.ExpireTimeSpan = TimeSpan.FromHours(2); + }); + +// NEU: Erlaubt Blazor-Komponenten, den Login-Status abzufragen +builder.Services.AddCascadingAuthenticationState(); +builder.Services.AddScoped(); + // Hinzufügen des Blazor Service und die Interagierbarkeit des Frontends builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); @@ -36,6 +55,11 @@ if (!app.Environment.IsDevelopment()) // Erlauben des Zugriffs auf wwwroot Dir app.UseStaticFiles(); + +// NEU: Authentifizierungs-Middleware aktivieren (MUSS vor Antiforgery stehen!) +app.UseAuthentication(); +app.UseAuthorization(); + // Schützen vor CSRF Attacken app.UseAntiforgery(); @@ -43,5 +67,30 @@ app.UseAntiforgery(); app.MapRazorComponents() .AddInteractiveServerRenderMode(); +// ========================================== +// SCHRITT 3: HIER EINGEFÜGT (Login-Endpunkt) +// ========================================== +app.MapPost("/api/auth/login", async ( + [FromForm] string username, + [FromForm] string password, + HttpContext httpContext) => +{ + // Statischer User (Für SecDevOps später via Environment Variable aus K8s-Secret laden!) + const string StaticUser = "admin"; + const string StaticPassword = "DevOpsPassword2026!"; + + if (username == StaticUser && password == StaticPassword) + { + var claims = new List { new Claim(ClaimTypes.Name, username) }; + var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); + + await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); + + return Results.Redirect("/"); // Erfolgreich eingeloggt -> zur Startseite + } + + return Results.Redirect("/login?error=true"); // Fehler -> zurück zum Login +}); + // Webserver wird gestartet. Port 8080 wird eröffnet app.Run();