Skip to main content

Authentifizierung und Autorisierung

Alle Aufrufe der REST-Schnittstelle sind geschützt. Die Plattform validiert bei jeder Anfrage ein JSON Web Token (JWT), das von Keycloak (dem Identity-Provider der Plattform) ausgestellt wird. Das Token wird als Bearer-Token im Authorization-Header mitgeschickt:

Authorization: Bearer <access_token>

Keycloak stellt das Token über einen OAuth2-Flow aus. Für externe Anbindungen werden zwei Flows unterstützt:

  • Client-Credentials-Flow – für System-zu-System-Anbindungen ohne Nutzerinteraktion (empfohlen für Integrationen).
  • Authorization-Code-Flow – für Anwendungen, in denen sich ein menschlicher Nutzer interaktiv anmeldet.

Welche Zugangsdaten (Client, Secret, Realm-URL) Sie verwenden, erhalten Sie vom Betreiber der Plattform.

Voraussetzungen

Damit ein Token für die API akzeptiert wird, muss es zwei Bedingungen erfüllen:

  1. Der roles-Claim enthält die Rolle ROLE_SERVICEUSER (für lesenden und schreibenden Zugriff auf die regulären Endpunkte).
  2. Der groups-Claim enthält genau einen Eintrag der Form TENANT_<name>, der Ihren Tenant bestimmt. Über diesen Eintrag wird die mandantengetrennte Datenhaltung aufgelöst.

Beide Claims werden beim Anlegen des Clients bzw. Nutzers durch den Plattform-Betreiber konfiguriert – Sie müssen dazu nichts weiter unternehmen.

Endpunkte

Keycloak stellt die relevanten Endpunkte unter der Realm-Basis-URL bereit. Die folgenden Platzhalter kommen in den Beispielen zum Einsatz:

PlatzhalterBedeutungBeispiel
<keycloak-host>Host der Keycloak-Instanz (inkl. /auth-Pfad)https://auth.example.com/auth
<realm>Name des Realmshetida-platform-standalone
<platform-host>Host der Plattform-APIhttps://platform.example.com

Daraus ergibt sich:

  • Token-Endpunkt: <keycloak-host>/realms/<realm>/protocol/openid-connect/token
  • Authorization-Endpunkt: <keycloak-host>/realms/<realm>/protocol/openid-connect/auth
  • API-Basis-URL: <platform-host>/api

Client-Credentials-Flow (empfohlen)

Beim Client-Credentials-Flow authentifiziert sich Ihre Anwendung mit einer Client-ID und einem Client-Secret – ohne Nutzerkontext. Sie erhalten ein Access-Token direkt vom Token-Endpunkt und verwenden es für die API-Aufrufe.

Beispiel in Python

Das folgende Beispiel holt ein Token und liest anschließend die Asset-Typen des Tenants aus. Es verwendet die Bibliothek requests (pip install requests).

import requests

KEYCLOAK_HOST = "https://<keycloak-host>" # inkl. /auth, falls konfiguriert
REALM = "<realm>"
PLATFORM_HOST = "https://<platform-host>"

CLIENT_ID = "<client-id>"
CLIENT_SECRET = "<client-secret>"

TOKEN_URL = f"{KEYCLOAK_HOST}/realms/{REALM}/protocol/openid-connect/token"
API_BASE = f"{PLATFORM_HOST}/api"


def fetch_access_token() -> str:
response = requests.post(
TOKEN_URL,
data={"grant_type": "client_credentials"},
auth=(CLIENT_ID, CLIENT_SECRET), # HTTP Basic Authentication
timeout=10,
)
response.raise_for_status()
return response.json()["access_token"]


def main() -> None:
token = fetch_access_token()
headers = {"Authorization": f"Bearer {token}"}

response = requests.get(f"{API_BASE}/asset-types", headers=headers, timeout=10)
response.raise_for_status()

for asset_type in response.json():
print(asset_type)


if __name__ == "__main__":
main()
Token-Lebensdauer

Access-Tokens sind nur kurz gültig (in der Regel wenige Minuten). Fordern Sie für lang laufende Prozesse rechtzeitig ein neues Token an, statt ein bestehendes zu zwischenspeichern.

Secrets schützen

Behandeln Sie das Client-Secret wie ein Passwort: Nicht in Quellcode-Repositories einchecken, sondern z. B. über Umgebungsvariablen oder einen Secret-Store bereitstellen.

Authorization-Code-Flow

Für Anwendungen mit interaktiver Nutzeranmeldung (z. B. eine Web-App im Namen eines angemeldeten Nutzers) wird der Authorization-Code-Flow verwendet. Der grobe Ablauf:

  1. Die Anwendung leitet den Nutzer auf den Authorization-Endpunkt von Keycloak weiter (response_type=code, mit Ihrer client_id und einer registrierten redirect_uri). Für öffentliche Clients (ohne Secret) ist zusätzlich PKCE zu verwenden.
  2. Nach erfolgreicher Anmeldung leitet Keycloak zurück zur redirect_uri und übergibt einen einmaligen Authorization Code.
  3. Die Anwendung tauscht den Code am Token-Endpunkt gegen ein Access-Token (grant_type=authorization_code) ein.
  4. Das Access-Token wird – wie beim Client-Credentials-Flow – als Bearer-Token an die API gesendet.

Auch hier gelten die Voraussetzungen an roles und groups: Der angemeldete Nutzer muss über die Rolle ROLE_SERVICEUSER (bzw. ROLE_USER) und die passende TENANT_<name>-Gruppe verfügen.

Die konkreten Parameter (öffentlicher Client, erlaubte redirect_uris) legt der Plattform-Betreiber für Ihre Anwendung fest.

Autorisierung

Nach erfolgreicher Authentifizierung entscheidet die Plattform anhand von drei Ebenen, was ein Aufrufer tun darf:

  1. Rollen – grobgranular, aus dem roles-Claim des Tokens.
  2. Tenant-Isolation – die mandantengetrennte Datenhaltung über den groups-Claim (TENANT_<name>).
  3. Zugriffsrechte auf Knotenebene – feingranular pro Knoten der Asset-Hierarchie.

Rollen

Die Rollen stehen im roles-Claim des Tokens. Für die REST-Schnittstelle sind insbesondere relevant:

RolleBedeutung
ROLE_USERStandard-Lese-/Schreibzugriff (interaktive Nutzer)
ROLE_SERVICEUSERwie ROLE_USER, für nicht-interaktive Zugriffe (Client-Credentials)
ROLE_ADMINadministrative Endpunkte; umgeht die Prüfung auf Knotenebene
ROLE_SERVICEADMINwie ROLE_ADMIN, für nicht-interaktive Zugriffe
ROLE_CUSTOM_PANEL_TEMPLATE_CREATORCode und Vorlagen von Customizable Panels bearbeiten
ROLE_HETIDA_DESIGNER_CONFIGURATORKonfiguration der hetida-designer-Integration
ROLE_OPC_UA_USEROPC-UA-spezifische Endpunkte

Die meisten Endpunkte verlangen ROLE_USER oder ROLE_SERVICEUSER. Externe Integrationen (Client-Credentials) erhalten typischerweise ROLE_SERVICEUSER (siehe Voraussetzungen).

Tenant-Isolation

Jedes Token gehört zu genau einem Tenant, bestimmt durch den Eintrag TENANT_<name> im groups-Claim. Die Datenhaltung ist mandantengetrennt (per Row-Level-Security in der Datenbank): Ein Aufrufer sieht ausschließlich Daten seines Tenants. Fehlt der Tenant-Eintrag oder sind mehrere TENANT_-Einträge vorhanden, kann der Tenant nicht aufgelöst werden und der Zugriff schlägt fehl.

Zugriffsrechte auf Knotenebene

Über die Rollen hinaus wird der Zugriff auf einzelne Knoten der Asset-Hierarchie feingranular geprüft. Rechte werden pro Nutzer oder pro Gruppe auf Knoten vergeben und als CRUD-Berechtigungen ausgedrückt:

RechtBedeutung
CAnlegen (Create)
RLesen (Read)
UÄndern (Update)
DLöschen (Delete)
  • Lesende Endpunkte, die Listen oder Teilbäume der Hierarchie zurückgeben, werden serverseitig gefiltert: Knoten ohne Leserecht (R) erscheinen nicht in der Antwort.
  • Schreibende/löschende Zugriffe erfordern das entsprechende Recht (U bzw. D) auf dem Zielknoten.
  • Aufrufer mit ROLE_ADMIN oder ROLE_SERVICEADMIN umgehen diese Prüfung.

Die Vergabe von Knotenrechten erfolgt über die REST-Endpunkte der Tags user-rights und group-rights (siehe REST-Schnittstelle).

Fehlerbehandlung

HTTP-StatusUrsacheAbhilfe
401 UnauthorizedKein, ungültiges oder abgelaufenes TokenNeues Token anfordern und den Authorization-Header prüfen.
403 ForbiddenToken gültig, aber fehlende Rolle, falscher/kein Tenant oder fehlendes Zugriffsrecht auf dem ZielknotenPrüfen, ob der Client/Nutzer ROLE_SERVICEUSER, die korrekte TENANT_<name>-Gruppe sowie das nötige Knotenrecht (R/U/D) besitzt.