Paralleles WebGUI mit Kestrel, Token-Sicherung und SSE-Logs implementiert

This commit is contained in:
Richard
2026-09-07 21:55:51 +02:00
parent 28b3aedec7
commit 10f928eb4e
36 changed files with 3114 additions and 266 deletions
@@ -0,0 +1,71 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using PolyTrader.Web.Configuration;
using PolyTrader.Web.Security;
namespace PolyTrader.Web.Endpoints
{
public static class AuthEndpoints
{
public record LoginRequest(string? Token);
public record TokenResponse(string Token);
public static IEndpointRouteBuilder MapAuthEndpoints(this IEndpointRouteBuilder routes)
{
var group = routes.MapGroup("/api/auth");
group.MapGet("/status", (HttpContext context, IOptions<WebUiOptions> optionsProvider) =>
{
var options = optionsProvider.Value;
bool isConfigured = !string.IsNullOrWhiteSpace(options.AuthToken);
bool isAuthenticated = TokenAuthMiddleware.IsAuthenticated(context, options.AuthToken);
return Results.Ok(new
{
isConfigured,
isAuthenticated
});
});
group.MapPost("/login", (LoginRequest req, HttpContext context, IOptions<WebUiOptions> optionsProvider) =>
{
var options = optionsProvider.Value;
if (string.IsNullOrWhiteSpace(options.AuthToken))
{
return Results.BadRequest(new { error = "Kein Zugangs-Token im System konfiguriert." });
}
if (string.IsNullOrWhiteSpace(req.Token) || !TokenAuthMiddleware.ValidateToken(req.Token, options.AuthToken))
{
return Results.Json(new { error = "Ungültiges Zugangs-Token." }, statusCode: StatusCodes.Status401Unauthorized);
}
context.Response.Cookies.Append(TokenAuthMiddleware.CookieName, req.Token.Trim(), new CookieOptions
{
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Secure = context.Request.IsHttps,
Expires = DateTimeOffset.UtcNow.AddHours(options.SessionTimeoutHours),
Path = "/"
});
return Results.Ok(new { success = true });
});
group.MapPost("/logout", (HttpContext context) =>
{
context.Response.Cookies.Delete(TokenAuthMiddleware.CookieName, new CookieOptions
{
Path = "/"
});
return Results.Ok(new { success = true });
});
return routes;
}
}
}