Files
Watcher/watcher-monitoring/Program.cs
triggermeelmo ad9b6bfdaf
All checks were successful
Gitea CI/CD / dotnet-build-and-test (push) Successful in 10m0s
Gitea CI/CD / Set Tag Name (push) Successful in 5s
Gitea CI/CD / docker-build-and-push (push) Successful in 11m39s
Gitea CI/CD / Create Tag (push) Successful in 5s
OIDC Integration
2026-01-21 10:05:03 +01:00

196 lines
6.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.OpenApi.Models;
using Serilog;
using watcher_monitoring.Configuration;
using watcher_monitoring.Data;
var builder = WebApplication.CreateBuilder(args);
// Serilog konfigurieren nur Logs, die nicht von Microsoft stammen
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.File(
"logs/watcher-.log",
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}",
rollingInterval: RollingInterval.Day
)
.CreateLogger();
builder.Host.UseSerilog();
// ---------- Konfiguration ----------
DotNetEnv.Env.Load();
builder.Configuration.AddEnvironmentVariables();
// OIDC-Einstellungen laden
var oidcSettings = OidcSettings.FromEnvironment();
builder.Services.AddSingleton(oidcSettings);
// Konfiguration laden
var configuration = builder.Configuration;
// DbContext - Nur SQLite wird unterstützt
var sqliteConnectionString = configuration.GetConnectionString("Sqlite")
?? configuration["Database:ConnectionStrings:Sqlite"]
?? "Data Source=./persistence/watcher.db";
builder.Services.AddDbContext<WatcherDbContext>((serviceProvider, options) =>
{
options.UseSqlite(sqliteConnectionString);
});
// Add services to the container.
builder.Services.AddControllersWithViews();
// Cookie-basierte Authentifizierung
var authBuilder = builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Auth/Login";
options.LogoutPath = "/Auth/Logout";
options.AccessDeniedPath = "/Auth/AccessDenied";
options.ExpireTimeSpan = TimeSpan.FromHours(8);
options.SlidingExpiration = true;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Lax;
});
// OIDC-Authentifizierung (wenn aktiviert)
if (oidcSettings.IsValid)
{
Log.Information("OIDC-Authentifizierung aktiviert für Authority: {Authority}", oidcSettings.Authority);
authBuilder.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = oidcSettings.Authority;
options.ClientId = oidcSettings.ClientId;
options.ClientSecret = oidcSettings.ClientSecret;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.CallbackPath = oidcSettings.CallbackPath;
options.SignedOutCallbackPath = "/signout-callback-oidc";
options.Scope.Clear();
foreach (var scope in oidcSettings.GetScopes())
{
options.Scope.Add(scope);
}
options.TokenValidationParameters.NameClaimType = oidcSettings.ClaimUsername;
options.TokenValidationParameters.RoleClaimType = "roles";
});
}
else if (oidcSettings.Enabled)
{
Log.Warning("OIDC ist aktiviert aber nicht korrekt konfiguriert. Erforderlich: OIDC_AUTHORITY, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET");
}
builder.Services.AddAuthorization();
// Health Checks
builder.Services.AddHealthChecks();
// Swagger API-Dokumentation
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Watcher-Server API", Version = "v1" });
// Nur API-Controller dokumentieren (mit [ApiController]-Attribut)
options.DocInclusionPredicate((docName, apiDesc) =>
{
var controllerActionDescriptor = apiDesc.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
if (controllerActionDescriptor == null) return false;
// Nur Controller mit [ApiController]-Attribut einbeziehen
return controllerActionDescriptor.ControllerTypeInfo
.GetCustomAttributes(typeof(ApiControllerAttribute), true).Any();
});
});
var app = builder.Build();
// Stelle sicher, dass das persistence-Verzeichnis existiert
var persistenceDir = Path.Combine(Directory.GetCurrentDirectory(), "persistence");
if (!Directory.Exists(persistenceDir))
{
Log.Information("Erstelle persistence-Verzeichnis: {PersistenceDir}", persistenceDir);
Directory.CreateDirectory(persistenceDir);
}
// Datenbank-Migration beim Start ausführen
using (var scope = app.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<WatcherDbContext>();
try
{
Log.Information("Führe Datenbank-Migrationen aus...");
dbContext.Database.Migrate();
Log.Information("Datenbank-Migrationen erfolgreich angewendet");
// Standard-Admin-User erstellen, falls noch kein User existiert
if (!dbContext.Users.Any())
{
Log.Information("Erstelle Standard-Admin-User...");
var adminUser = new watcher_monitoring.Models.User
{
Username = "admin",
Email = "admin@watcher.local",
Password = BCrypt.Net.BCrypt.HashPassword("admin"),
IsActive = true,
CreatedAt = DateTime.UtcNow,
LastLogin = DateTime.UtcNow
};
dbContext.Users.Add(adminUser);
dbContext.SaveChanges();
Log.Information("Standard-Admin-User erstellt (Username: admin, Passwort: admin)");
}
}
catch (Exception ex)
{
Log.Error(ex, "Fehler beim Ausführen der Datenbank-Migrationen");
throw;
}
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
// 🔹 Swagger aktivieren
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Watcher-Server API v1");
options.RoutePrefix = "api/v1/swagger";
});
app.UseAuthentication();
app.UseAuthorization();
// Health Check Endpoint
app.MapHealthChecks("/health");
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();