🔐 Keycloak & Plusserver

Identity & Access Management mit Keycloak auf deutscher Cloud-Infrastruktur - Integration in .NET 8 Backends

Keycloak 26.x Plusserver - Made in Germany .NET 8 Integration

Was ist Keycloak?

Keycloak ist eine Open-Source Identity & Access Management (IAM) Lösung, entwickelt von Red Hat und jetzt ein CNCF-Projekt. Es bietet Single Sign-On (SSO), Identity Brokering, User Federation und feingranulare Autorisierung - ohne eigenen Code schreiben zu müssen.

👤

Single Sign-On (SSO)

Einmal anmelden, überall eingeloggt. Unterstützt OpenID Connect, SAML 2.0 und OAuth 2.0.

🔗

Identity Brokering

Verbinde externe Identity Provider wie Google, Microsoft, GitHub oder LDAP/Active Directory.

🔒

Feingranulare Autorisierung

Realm-Rollen, Client-Rollen, Gruppen und Policy-basierte Zugriffskontrolle.

📱

Multi-Faktor Auth (MFA)

OTP, WebAuthn/Passkeys, SMS und konfigurierbare Authentifizierungs-Flows.

🎨

Anpassbare UI

Themes für Login-Seiten, Account-Konsole und Admin-Konsole. Vollständig customizable.

🛠

Admin Console

Web-basiertes Management für Users, Clients, Rollen, Sessions, Events und mehr.

Keycloak auf einen Blick

EigenschaftDetails
TypOpen Source IAM (CNCF)
Aktuelle Version26.x (Stand 2026)
ProtokolleOpenID Connect, OAuth 2.0, SAML 2.0
DatenbankPostgreSQL (empfohlen), MySQL, MariaDB
DeploymentDocker, Kubernetes, Bare Metal, Cloud
LizenzApache License 2.0
Neue Features (v26)Passkeys, Organizations (CIAM), FAPI 2.0, OAuth 2.0 Server Metadata

Keycloak Kernkonzepte

Klicke auf die Konzepte, um Details zu sehen:

🌐 Realms

Ein Realm ist der oberste Mandanten-Container. Er verwaltet Users, Credentials, Rollen und Gruppen. Realms sind vollständig voneinander isoliert. Der master-Realm ist für die Administration reserviert - erstelle für jede Anwendungsdomäne einen eigenen Realm.

Beispiel: meine-firma-prod, meine-firma-dev

💻 Clients

Clients sind Anwendungen/Services, die Keycloak zur Authentifizierung nutzen. Jeder Client hat ein Protokoll (OIDC oder SAML) und einen Access-Type:

  • Public - Frontend SPA (kein Secret)
  • Confidential - Server-seitige App (mit Secret)
  • Bearer-only - API, validiert nur Tokens

👥 Users & Groups

Users haben Attribute, Credentials (Passwort, OTP), Gruppenmitgliedschaften und Rollenzuweisungen. Users können lokal erstellt, aus LDAP/AD importiert oder über externe Identity Provider föderiert werden.

Groups sind hierarchische Container. Rollen-Zuweisungen auf Gruppen werden an alle Mitglieder vererbt.

👑 Roles

Zwei Typen von Rollen:

  • Realm Roles - Global im Realm (z.B. "admin", "user")
  • Client Roles - Scoped auf einen Client (z.B. "api-admin")

Rollen können komposit sein (andere Rollen enthalten). Sie sind der primäre Mechanismus für RBAC.

🔗 Identity Providers

Externe Authentifizierungsquellen. Keycloak kann als Broker fungieren und leitet User an den externen IdP weiter:

  • Social - Google, GitHub, Microsoft, Facebook
  • Enterprise - SAML IdP, OIDC IdP
  • User Federation - LDAP, Active Directory

🔄 Authentication Flows

Konfigurierbare Workflows, die definieren, welche Schritte ein User beim Login durchläuft. Flows bestehen aus geordneten Ausführungen:

  • Username/Password Formular
  • OTP-Eingabe
  • WebAuthn/Passkeys
  • Conditional MFA (z.B. nur für bestimmte Clients)
Keycloak Konzept-Hierarchie
🌐 Realm: "meine-firma-prod"
💻 Client: Frontend SPA Public / OIDC
💻 Client: Backend API Confidential / OIDC
💻 Client: Admin Tool Confidential / OIDC
👥 Users + Groups
👑 Realm Roles + Client Roles
🔗 Identity Providers

Authentifizierungs-Protokolle

Keycloak unterstützt die wichtigsten Standards für Identity Management:

📂

OpenID Connect (OIDC)

Primäres Protokoll. Basiert auf OAuth 2.0. Liefert ID Token, Access Token und Refresh Token.


Empfohlen für .NET 8
📄

SAML 2.0

Enterprise-Föderations-Protokoll. Keycloak kann als SAML IdP und SAML SP agieren.


Enterprise
🔓

OAuth 2.0

Underlying Framework. Token Introspection, Revocation, Device Authorization, PKCE.


Framework

OIDC Authorization Code Flow (mit PKCE)

Der empfohlene Flow für Web-Anwendungen mit .NET 8:

Dein .NET 8 Backend oder SPA startet den Login-Prozess und leitet den User zu Keycloak weiter.
💻 .NET 8 App
Keycloak zeigt das Login-Formular, validiert Credentials, führt MFA durch und gibt einen Authorization Code zurück.
🔐 Keycloak Login + Auth Code
Die App tauscht den Authorization Code gegen Tokens (ID Token, Access Token, Refresh Token).
🆔 Token Exchange Code → Tokens
Access Token wird bei jeder API-Anfrage im Authorization-Header mitgeschickt. Das Backend validiert die Signatur und Claims.
API-Zugriff Bearer Token
💡

PKCE (Proof Key for Code Exchange) schützt vor Authorization Code Interception Attacks. Immer aktivieren!

Token-Typen

TokenZweckLebensdauer
ID Token (JWT)Enthält User-Identität (Name, Email, Rollen)Kurz (5-15 Min)
Access Token (JWT)Autorisierung für API-ZugriffeKurz (5-15 Min)
Refresh TokenNeues Access Token anfordern ohne Re-LoginLang (Stunden/Tage)

Plusserver - Deutscher Cloud-Anbieter

Plusserver ist ein führender deutscher Cloud-Provider mit Fokus auf digitale Souveränität und DSGVO-Konformität. Rechenzentren in Köln, Düsseldorf und Hamburg.

☁️

pluscloud open

OpenStack-basierte IaaS. Erste deutsche Enterprise Cloud auf Sovereign Cloud Stack (SCS/Gaia-X).


BSI C5 Type II
☸️

PSKE - Managed K8s

CNCF-zertifizierte Kubernetes-Plattform auf Basis von SAP Gardener. Autoscaling, Hibernation.


CNCF Certified
🔐

Keycloak as a Service

Vollständig gemanagtes Keycloak in deutschen Rechenzentren. Installation, Monitoring, Updates inklusive.


Managed

Zertifizierungen & Compliance

📋

BSI C5 Type II

Bundesamt für Sicherheit in der IT

🔒

ISO 27001

Informationssicherheit

🇪🇺

DSGVO

EU-Datenschutz-konform

💳

PCI DSS

Payment Card Industry

Keycloak as a Service (KCaaS) - Pricing

Instanz

€0,44 /Stunde
  • 4 vCPU
  • 8 GB RAM
  • Managed Updates
  • 24/7 Support

Storage

€14,30 /50 GB
  • SSD-basiert
  • Automatische Backups
  • Skalierbar

Inklusive

Features
  • SSO & MFA
  • Admin Console
  • BSI C5 konform
  • Kein Mindestvertrag

pluscloud open - Preise

RessourcePreisHinweis
vCPU€0,0205/StundePay-as-you-go
vRAM€0,007/Stunde pro GBPay-as-you-go
Storage€0,09/GB/MonatSSD
Load Balancer€0,068/StundeLBaaS
Public IP€0,003/Stunde
TrafficKostenlosFair Use
Object Storage20 GB kostenlosS3 + Swift kompatibel

Keycloak Deployment auf Plusserver

Drei Optionen - wähle die passende für dein Team:

Option A: Keycloak as a Service Empfohlen für schnellen Start

Plusserver übernimmt Installation, Monitoring, Updates und Backups.

1Im CloudHub Portal bestellen
  • CloudHub Portal aufrufen
  • Keycloak as a Service auswählen
  • Instanzgröße und Region wählen
  • Instanz wird automatisch provisioniert
2Realm und Clients konfigurieren
  • Admin Console öffnen (URL von Plusserver bereitgestellt)
  • Neuen Realm erstellen
  • Client für dein .NET 8 Backend anlegen
  • Rollen und User konfigurieren

Vorteil: Kein Infrastruktur-Management, BSI C5 / DSGVO out-of-the-box, 24/7 Support, Pay-as-you-go.

Option B: Self-Managed auf pluscloud open Volle Kontrolle

docker-compose.yml
version: '3.9'
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    restart: unless-stopped

  keycloak:
    image: quay.io/keycloak/keycloak:26.5
    command: start
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: ${DB_PASSWORD}
      KC_HOSTNAME: auth.meine-firma.de
      KC_PROXY_HEADERS: xforwarded
      KC_HTTP_ENABLED: "true"
      KC_HEALTH_ENABLED: "true"
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
    ports:
      - "8080:8080"
    depends_on:
      - postgres
    restart: unless-stopped

volumes:
  pgdata:

Nginx Reverse Proxy

nginx.conf
server {
    listen 443 ssl http2;
    server_name auth.meine-firma.de;

    ssl_certificate     /etc/letsencrypt/live/auth.meine-firma.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/auth.meine-firma.de/privkey.pem;

    location / {
        proxy_pass         http://localhost:8080;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   X-Forwarded-Host $host;
        proxy_buffer_size 128k;
        proxy_buffers     4 256k;
    }
}

Option C: PSKE Managed Kubernetes Production HA

keycloak-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
spec:
  replicas: 2
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
    spec:
      containers:
        - name: keycloak
          image: quay.io/keycloak/keycloak:26.5
          args: ["start"]
          env:
            - name: KC_DB
              value: "postgres"
            - name: KC_DB_URL
              value: "jdbc:postgresql://postgres-svc:5432/keycloak"
            - name: KC_DB_USERNAME
              valueFrom:
                secretKeyRef:
                  name: keycloak-db
                  key: username
            - name: KC_DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: keycloak-db
                  key: password
            - name: KC_HOSTNAME
              value: "auth.meine-firma.de"
            - name: KC_PROXY_HEADERS
              value: "xforwarded"
            - name: KC_HEALTH_ENABLED
              value: "true"
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 8080
          livenessProbe:
            httpGet:
              path: /health/live
              port: 8080

Vergleich der Deployment-Optionen

AspektKCaaS (Managed)pluscloud openPSKE (K8s)
BetriebsaufwandMinimalHochMittel
SkalierbarkeitBegrenztManuellAuto
HA built-inJaManuellMit Replicas
ComplianceVorzertifiziertSelf-managedInfra vorzertifiziert
AnpassbarkeitBegrenztVollVoll
Best fürKleine/mittlere TeamsCustom RequirementsCloud-native Teams

Keycloak + .NET 8 Backend Integration

Schritt-für-Schritt Anleitung zur Absicherung deines .NET 8 Backends mit Keycloak.

1NuGet-Pakete installieren
Terminal
# JWT Bearer Token Validierung (für APIs)
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

# Azure Identity (falls auch Key Vault genutzt wird)
dotnet add package Azure.Identity

# Optional: Keycloak-spezifisches Paket (vereinfacht Config)
dotnet add package Keycloak.AuthServices.Authentication
dotnet add package Keycloak.AuthServices.Authorization
2Keycloak Client in Admin Console anlegen
  • Keycloak Admin Console öffnen
  • Realm auswählen oder erstellen
  • Clients → Create client
  • Client ID: z.B. mein-dotnet-api
  • Client Protocol: openid-connect
  • Access Type: confidential
  • Valid Redirect URIs: https://localhost:5001/*
  • Im Tab Credentials: Client Secret kopieren

Für eine reine API (Bearer-only) kann der Access Type auch auf bearer-only gesetzt werden - dann ist kein Login-Flow nötig.

3appsettings.json konfigurieren
appsettings.json
{
  "Keycloak": {
    "realm": "mein-realm",
    "auth-server-url": "https://auth.meine-firma.de/",
    "ssl-required": "external",
    "resource": "mein-dotnet-api",
    "credentials": {
      "secret": "DEIN-CLIENT-SECRET"
    }
  }
}

Das Client Secret gehört nicht in den Code oder Git! Nutze User Secrets (lokal) oder Azure Key Vault (Produktion).

4Program.cs - JWT Bearer Authentication
Program.cs - Standard
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);

var keycloakUrl = builder.Configuration["Keycloak:auth-server-url"];
var realm = builder.Configuration["Keycloak:realm"];
var audience = builder.Configuration["Keycloak:resource"];

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = $"{keycloakUrl}realms/{realm}";
        options.Audience = audience;
        options.RequireHttpsMetadata = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidIssuer = $"{keycloakUrl}realms/{realm}"
        };
    });

builder.Services.AddAuthorization();
builder.Services.AddControllers();

// Claims Transformation für Keycloak-Rollen
builder.Services.AddTransient<IClaimsTransformation,
    KeycloakRoleClaimsTransformation>();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Program.cs - Keycloak.AuthServices
using Keycloak.AuthServices.Authentication;
using Keycloak.AuthServices.Authorization;

var builder = WebApplication.CreateBuilder(args);

// Keycloak Auth in einer Zeile!
builder.Services
    .AddKeycloakWebApiAuthentication(builder.Configuration);

// Keycloak-spezifische Autorisierung
builder.Services.AddKeycloakAuthorization(options =>
{
    options.EnableRolesMapping =
        RolesClaimTransformationSource.ResourceAccess;
    options.RolesResource = "mein-dotnet-api";
});

builder.Services.AddAuthorization();
builder.Services.AddControllers();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
5Keycloak Rollen-Mapping (wichtig!)

Achtung: Keycloak verschachtelt Rollen in realm_access.roles und resource_access.<client>.roles im JWT. .NET mappt diese NICHT automatisch auf ClaimTypes.Role!

KeycloakRoleClaimsTransformation.cs
using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;

public class KeycloakRoleClaimsTransformation
    : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(
        ClaimsPrincipal principal)
    {
        var identity = (ClaimsIdentity)principal.Identity!;

        // Realm Roles
        var realmAccess = principal.FindFirst("realm_access");
        if (realmAccess != null)
        {
            var roles = JsonDocument
                .Parse(realmAccess.Value)
                .RootElement.GetProperty("roles");

            foreach (var role in roles.EnumerateArray())
            {
                identity.AddClaim(new Claim(
                    ClaimTypes.Role,
                    role.GetString()!));
            }
        }

        return Task.FromResult(principal);
    }
}
6API-Endpoints absichern
Controller mit Autorisierung
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class DataController : ControllerBase
{
    // Nur authentifizierte User
    [HttpGet]
    [Authorize]
    public IActionResult GetAll()
        => Ok("Authentifiziert!");

    // Nur User mit Rolle "admin"
    [HttpGet("admin")]
    [Authorize(Roles = "admin")]
    public IActionResult GetAdmin()
        => Ok("Admin-Bereich!");

    // Policy-basierte Autorisierung
    [HttpDelete("{id}")]
    [Authorize(Policy = "RequireManager")]
    public IActionResult Delete(int id)
        => Ok($"Gelöscht: {id}");
}

// In Program.cs Policy registrieren:
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireManager", policy =>
        policy.RequireRole("manager", "admin"));
});
7Vollständiges Beispiel: Program.cs
Program.cs - Production Ready
using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;

// ==========================================
// Keycloak JWT Bearer Authentication
// ==========================================
var kcUrl = config["Keycloak:auth-server-url"];
var realm = config["Keycloak:realm"];
var audience = config["Keycloak:resource"];

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt =>
    {
        opt.Authority = $"{kcUrl}realms/{realm}";
        opt.Audience = audience;
        opt.RequireHttpsMetadata = true;
        opt.TokenValidationParameters = new()
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidIssuer = $"{kcUrl}realms/{realm}"
        };
    });

// Keycloak Rollen-Mapping
builder.Services
    .AddTransient<IClaimsTransformation,
        KeycloakRoleClaimsTransformation>();

// Autorisierung mit Policies
builder.Services.AddAuthorization(opt =>
{
    opt.AddPolicy("AdminOnly",
        p => p.RequireRole("admin"));
    opt.AddPolicy("ManagerOrAdmin",
        p => p.RequireRole("manager", "admin"));
});

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

Best Practices

✓ Do's

  • TLS überall erzwingen - HTTP in Produktion komplett deaktivieren
  • Separate Realms pro Umgebung (Dev/Staging/Prod)
  • Managed Identity / Passkeys für Admin-Zugriff
  • PostgreSQL als Datenbank verwenden
  • Min. 2 Replicas für High Availability
  • MFA erzwingen für sensible Realms
  • Event Logging aktivieren und an SIEM exportieren
  • Signing Keys regelmäßig rotieren
  • Admin Console auf separatem Hostname betreiben
  • KCaaS von Plusserver für DSGVO-Konformität

✗ Don'ts

  • H2-Datenbank in Produktion verwenden
  • Master-Realm für App-User nutzen
  • Client Secrets im Code hartcodieren
  • RequireHttpsMetadata = false in Produktion
  • Brute-Force-Protection deaktiviert lassen
  • Standard-Admin-Passwort beibehalten
  • Alle Protocols/Endpoints aktiviert lassen
  • Token-Validierung überspringen
  • Keycloak ohne Reverse Proxy exponieren
  • Updates ignorieren - jedes Release fixt CVEs

Environments-Strategie

UmgebungKeycloakSecret-QuellePlusserver
Development Docker lokal User Secrets -
Staging KCaaS oder PSKE Key Vault / K8s Secrets pluscloud open
Production KCaaS (HA) oder PSKE (2+ Replicas) Key Vault / Sealed Secrets pluscloud open (geo-redundant)

Gesamtarchitektur: .NET 8 + Keycloak + Plusserver

Production Setup auf Plusserver
Dein Frontend (SPA oder Mobile App) leitet den User zum Keycloak Login weiter.
📱 Frontend / SPA
Keycloak as a Service auf Plusserver. Authentifiziert den User und gibt JWT Tokens aus.
🔐 Keycloak (KCaaS) Plusserver - DE
Dein .NET 8 Backend validiert das JWT Token und prüft Rollen/Berechtigungen.
⚙️ .NET 8 API pluscloud open / PSKE
🗂 PostgreSQL Keycloak DB
🗂 App Database SQL Server / PG
📦 Object Storage S3-kompatibel

Wissenstest: Keycloak & Plusserver

Teste dein Wissen!

1. Was ist ein "Realm" in Keycloak?

2. Welches Protokoll wird für die .NET 8 Integration empfohlen?

3. Was bietet Plusserver als "KCaaS" an?

4. Warum braucht man eine Claims Transformation für Keycloak in .NET?

5. Welche Datenbank wird für Keycloak in Produktion empfohlen?

6. In welchen Städten betreibt Plusserver Rechenzentren?