diff --git a/Components/Pages/Home.razor b/Components/Pages/Home.razor
index df05023..66bb9c9 100644
--- a/Components/Pages/Home.razor
+++ b/Components/Pages/Home.razor
@@ -1,7 +1,40 @@
@page "/"
+@using Microsoft.AspNetCore.Components.Authorization
+@inject AuthenticationStateProvider AuthStateProvider
-Home
+Zahlen-Analyse
-
Hello, world!
+
+
+ Willkommen zurück, @context.User.Identity?.Name!
+ Deine Pocket-ID (Sub): @_userId
+
+
+ Abmelden
+
+
+
+ Bitte melde dich an, um deine Workspaces zu verwalten.
+
+ Mit Pocket-ID anmelden
+
+
+
-Welcome to your new app.
+@code {
+ private string _userId = string.Empty;
+
+ protected override async Task OnInitializedAsync()
+ {
+ var authState = await AuthStateProvider.GetAuthenticationStateAsync();
+ var user = authState.User;
+
+ if (user.Identity?.IsAuthenticated == true)
+ {
+ // Das ist der "sub"-Claim (Subject), den wir als OwnerId in RavenDB nutzen
+ _userId = user.FindFirst(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value
+ ?? user.FindFirst("sub")?.Value
+ ?? string.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Program.cs b/Program.cs
index b383c02..2f5b8c9 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,6 +1,13 @@
using ZahlenAnalyse.Web.Components;
using MudBlazor.Services;
using Raven.Client.Documents;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.IdentityModel.Tokens;
+using DotNetEnv;
+
+Env.Load();
var builder = WebApplication.CreateBuilder(args);
@@ -11,12 +18,43 @@ builder.Services.AddMudServices();
var store = new DocumentStore
{
- Urls = new[] { "http://localhost:8080" },
- Database = "ZahlenAnalyse"
+ Urls = new[] { builder.Configuration["RavenDb:Urls"] },
+ Database = builder.Configuration["RavenDb:Database"]
};
store.Initialize();
builder.Services.AddSingleton(store);
+builder.Services.AddCascadingAuthenticationState();
+
+builder.Services.AddAuthentication(options =>
+ {
+ options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
+ })
+ .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
+ .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
+ {
+ var pocketIdConfig = builder.Configuration.GetSection("PocketId");
+
+ options.Authority = pocketIdConfig["Authority"];
+ options.ClientId = pocketIdConfig["ClientId"];
+ options.ClientSecret = pocketIdConfig["ClientSecret"];
+
+ options.ResponseType = "code";
+ options.SaveTokens = true;
+
+ // Wichtig für lokale Dev-Umgebungen ohne HTTPS-Zertifikatsprüfung (falls nötig)
+ // options.RequireHttpsMetadata = false;
+
+ options.TokenValidationParameters = new TokenValidationParameters
+ {
+ NameClaimType = "name",
+ RoleClaimType = "roles"
+ };
+ });
+
+builder.Services.AddAuthorization();
+
var app = builder.Build();
@@ -33,7 +71,29 @@ app.UseHttpsRedirection();
app.UseAntiforgery();
app.MapStaticAssets();
+
+app.UseAuthentication();
+app.UseAuthorization();
+
app.MapRazorComponents()
.AddInteractiveServerRenderMode();
+
+app.MapGet("/login", async (HttpContext context) =>
+{
+ await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties
+ {
+ RedirectUri = "/"
+ });
+});
+
+app.MapGet("/logout", async (HttpContext context) =>
+{
+ await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
+ await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties
+ {
+ RedirectUri = "/"
+ });
+});
+
app.Run();
diff --git a/ZahlenAnalyse.Web.csproj b/ZahlenAnalyse.Web.csproj
index cc1ec20..d776c60 100644
--- a/ZahlenAnalyse.Web.csproj
+++ b/ZahlenAnalyse.Web.csproj
@@ -8,6 +8,8 @@
+
+