feat(auth): Anmeldung per OIDC mit Rollen aus Gruppen
Authorization Code mit PKCE, State und Nonce über openid-client 6.8.8; die Rolle kommt bei jeder Anmeldung aus dem Gruppen-Claim. Lokale Konten werden nie über den Namen übernommen, verknüpfen geht nur angemeldet. Getestet gegen einen Mock-IdP inklusive gefälschtem State, falscher Nonce und fremder Audience. Closes #016 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import type { Metadata } from "next";
|
||||
import { oeffentlicheAdresse } from "@/lib/adressen";
|
||||
import { Karte } from "@/components/karte";
|
||||
import { Status } from "@/components/status";
|
||||
import { oidcEinstellungen } from "@/server/auth/oidc";
|
||||
import { darf } from "@/server/auth/rechte";
|
||||
import { seiteSchuetzen } from "@/server/auth/zugang";
|
||||
import { benutzerListe } from "@/server/services/benutzer";
|
||||
@@ -13,8 +16,10 @@ import { TokenVerwaltung } from "./token-verwaltung";
|
||||
export const metadata: Metadata = { title: "Einstellungen" };
|
||||
|
||||
/** Einstellungen: eigene SSH-Schlüssel, CLI-Tokens, Passwort; für Admins die Benutzer. */
|
||||
export default async function Einstellungen() {
|
||||
export default async function Einstellungen({ searchParams }: { searchParams: Promise<{ sso?: string }> }) {
|
||||
const benutzer = await seiteSchuetzen("eigeneZugaenge", "/einstellungen");
|
||||
const sso = oidcEinstellungen();
|
||||
const ssoFehler = (await searchParams).sso;
|
||||
const admin = darf(benutzer.rolle, "benutzerVerwalten");
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
@@ -30,6 +35,35 @@ export default async function Einstellungen() {
|
||||
adresse={oeffentlicheAdresse("/", "http://localhost:3000").origin}
|
||||
/>
|
||||
{benutzer.passwortHash ? <PasswortAendern /> : null}
|
||||
{sso ? (
|
||||
<Karte titel="Anmeldung per SSO">
|
||||
<div className="flex flex-col gap-3">
|
||||
{ssoFehler === "schon_verknuepft" ? (
|
||||
<Status art="fehler">Dieses SSO-Konto gehört schon zu einem anderen Benutzer.</Status>
|
||||
) : null}
|
||||
{benutzer.oidcSubjekt ? (
|
||||
<Status art="erledigt">
|
||||
Mit {sso.anzeigename} verknüpft – die Rolle kommt bei jeder SSO-Anmeldung aus den Gruppen.
|
||||
</Status>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-muted text-sm">
|
||||
Dein Konto ist noch nicht mit {sso.anzeigename} verknüpft. Danach kannst du dich auch dort
|
||||
anmelden; die Rolle kommt dann aus den Gruppen beim Identity Provider.
|
||||
</p>
|
||||
<div>
|
||||
<a
|
||||
href="/api/v1/auth/oidc/start?verknuepfen=1"
|
||||
className="border-linie bg-panel-hoch text-text hover:border-muted inline-flex h-11 items-center rounded-lg border px-4 text-sm font-semibold sm:h-10"
|
||||
>
|
||||
Mit {sso.anzeigename} verknüpfen
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Karte>
|
||||
) : null}
|
||||
{admin ? <BenutzerVerwaltung anfang={await benutzerListe()} ich={benutzer.benutzername} /> : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user