Der Aufbau von Healthcare-Anwendungen auf Basis eines FHIR-Servers ist gängige Praxis geworden. FHIR-Server bieten standardisierte Speicherung und APIs für klinische Ressourcen und ermöglichen es Entwicklern, sich auf die Implementierung von Funktionen zu konzentrieren, anstatt die Infrastruktur für Gesundheitsdaten zu verwalten. Dies wirft jedoch eine wichtige Frage auf: Wie stellen Sie sicher, dass verschiedene Benutzer nur die Daten sehen, auf die sie berechtigt sind?
Ein Arzt sollte beispielsweise vollständigen Zugriff auf Patientenbeobachtungen haben – sowohl auf Laborbefunde als auch auf Vitalzeichen. Ein Labortechniker hingegen sollte nur abgeschlossene Laborbefunde sehen, die für seine Arbeit relevant sind. Die Implementierung dieser Art von feingranularer Zugriffskontrolle erfordert traditionell komplexe Logik auf Anwendungsebene, benutzerdefinierte Autorisierungsregeln und umfangreiche Tests.
Es gibt einen besseren Weg: einen standardbasierten Ansatz, der Ihren vorhandenen Identity Provider nutzt und keinerlei benutzerdefinierten Autorisierungscode in Ihrer Anwendung erfordert.
In diesem Beitrag erläutern wir, wie Sie eine ausgefeilte rollenbasierte Zugriffskontrolle (RBAC) für FHIR-Ressourcen mithilfe von Keycloak-Rollen (einer Open-Source-Lösung für Identity- und Access-Management), die SMART on FHIR V2-Scopes zugeordnet werden, und der automatischen Durchsetzung durch Aidbox implementieren. Das Beste daran: Derselbe API-Endpunkt gibt je nach anfragender Person unterschiedliche Daten zurück – vollständig transparent.
Das Problem: Ein Endpunkt, mehrere Zugriffsebenen
Stellen Sie sich vor, Sie entwickeln eine Healthcare-Anwendung auf Basis des FHIR-Servers mit zwei Benutzertypen:
Dr. Sarah (Ärztin)
- Muss alle Patientenbeobachtungen einsehen können
- Überprüft sowohl Laborbefunde als auch Vitalzeichen
- Trifft klinische Entscheidungen auf Grundlage vollständiger Patientendaten
Mike (Labortechniker)
- Arbeitet ausschließlich mit abgeschlossenen Laborbefunden
- Sollte keine Vitalzeichen oder vorläufigen Labordaten sehen
- Benötigt Zugriff, der auf seine spezifische Aufgabe beschränkt ist
Beide Benutzer rufen denselben API-Endpunkt auf: GET /fhir/Observation. Aber sie sollten völlig unterschiedliche Ergebnisse sehen.
Traditionell würden Entwickler dieses Problem durch folgende Maßnahmen lösen:
- Benutzerdefinierte Middleware zur Überprüfung von Benutzerrollen
- Komplexe Abfragefilter im Anwendungscode
- Separate API-Endpunkte oder Parameter für verschiedene Benutzertypen
- Umfangreiche Unit-Tests für jedes Autorisierungsszenario
- Wartungsaufwand bei sich ändernden Anforderungen
Dieser Ansatz funktioniert, ist jedoch schwer zu warten und fehleranfällig, wenn sich Anforderungen weiterentwickeln. Es gibt einen besseren Weg.
Die Lösung: SMART-Scopes treffen auf Keycloak-Rollen
SMART on FHIR V2 führt ein leistungsstarkes Konzept ein: Scopes mit Abfrageparametern. Anstatt nur breiten Zugriff zu gewähren wie „dieser Benutzer kann Observations lesen", können Sie exakte Regeln festlegen, zum Beispiel:
user/Observation.rs?category=laboratory&status=final
Dieser Scope bedeutet: „Der Benutzer kann Observations lesen und durchsuchen, jedoch nur Laborbeobachtungen mit dem Status ‚final'."
Durch die Kombination mit dem Composite-Rollen-System von Keycloak können wir:
- Granulare Berechtigungen als einfache Keycloak-Rollen definieren (jede repräsentiert einen SMART-Scope)
- Sie zu Aufgabenfunktionen zusammenfassen mithilfe von Composite-Rollen (wie „physician" oder „lab_technician")
- Composite-Rollen automatisch auflösen in SMART-Scopes im Zugriffstoken
- Aidbox die Regeln automatisch durchsetzen lassen – kein benutzerdefinierter Code erforderlich
So funktioniert der Ablauf:
User Login → Keycloak resolves roles → Token with SMART scopes →
Aidbox validates token → Automatic data filtering → Correct results
Implementierung: Aufbau der Rollenstruktur
Schritt 1: Basisrollen definieren (granulare SMART-Scopes)
In Keycloak erstellen wir Basisrollen, die direkt auf SMART on FHIR V2-Scopes abgebildet werden:
Basisrollen:
user/Patient.rs– Patientendaten lesen und durchsuchenuser/Encounter.rs– Begegnungen lesen und durchsuchenuser/Observation.rs– ALLE Observations lesen und durchsuchenuser/Observation.rs?category=laboratory&status=final– NUR abgeschlossene Laborbefunde lesen und durchsuchen
Diese Basisrollen sind die Bausteine. Jede repräsentiert eine spezifische Berechtigung mit optionalen Abfrageparameter-Einschränkungen.
Schritt 2: Composite-Rollen erstellen (Aufgabenfunktionen)
Als Nächstes kombinieren Sie Basisrollen zu Composite-Rollen, die reale Aufgabenfunktionen widerspiegeln:
Physician-Rolle (vollständiger klinischer Zugriff):
user/Patient.rsuser/Encounter.rsuser/Observation.rs
Lab-Technician-Rolle (beschränkt auf Laborbefunde):
user/Patient.rsuser/Observation.rs?category=laboratory&status=final
Beachten Sie, dass die Lab-Technician-Rolle den eingeschränkten Observation-Scope verwendet – dadurch wird der Zugriff auf Vitalzeichen oder Entwurfsergebnisse verhindert.
Schritt 3: Den Token-Mapper konfigurieren
Hier geschieht die eigentliche Magie. Keycloak wandelt Rollen in Zugriffstoken um. Das Token ist eine kleine, sichere Datei (JSON Web Token – JWT), die jede API-Anfrage begleitet und Aidbox mitteilt, was der Benutzer tun darf. Wir müssen Keycloak dazu bringen:
- Composite-Rollen (z. B. „physician") in ihre grundlegenden Basisrollen aufzulösen
- Diese Basisrollen im
scope-Claim des Tokens als SMART-Scopes einzuschließen - Den Claim
atv: "2"hinzuzufügen, um anzugeben, dass im Token SMART on FHIR-Scopes zur Verarbeitung vorhanden sind
Dies erreichen wir mithilfe eines benutzerdefinierten skriptbasierten Protocol Mappers. Wenn sich ein Labortechniker anmeldet, sieht sein Zugriffstoken folgendermaßen aus:
{
"sub": "lab_technician",
"scope": "user/Patient.rs
user/Observation.rs?category=laboratory&status=final",
"atv": "2"
}
Schritt 4: Aidbox für die automatische Durchsetzung konfigurieren
Dies ist der eleganteste Teil: Aidbox setzt die im Token definierten Zugriffsregeln automatisch durch. Alles, was Sie benötigen, ist:
- TokenIntrospector – Überprüft, ob das Token gültig und von Ihrer Keycloak-Instanz ausgestellt wurde:
{
"resourceType": "TokenIntrospector",
"jwt": {
"iss": "http://localhost:8888/realms/master"
},
"type": "jwt",
"jwks_uri":
"http://keycloak:8888/realms/master/protocol/openid-connect/certs",
"id": "external-auth-server",
"resourceType": "TokenIntrospector"
}
- AccessPolicy – Erlaubt Anfragen mit validierten Token:
{
"resourceType": "AccessPolicy",
"id": "keycloak-access-policy",
"engine": "matcho",
"matcho": {
"jwt": {
"iss": "http://localhost:8888/realms/master"
}
}
}
Das ist alles. Wenn Aidbox eine Anfrage mit einem Token empfängt, das atv: "2" und SMART-Scopes enthält, wird automatisch:
- Die Scopes analysiert, um erlaubte Ressourcentypen zu bestimmen
- Abfrageparameter-Filter aus den Scopes angewendet
- Nur Daten zurückgegeben, die den Scope-Einschränkungen entsprechen
- Anfragen für nicht autorisierte Ressourcentypen abgelehnt
Kein benutzerdefinierter Autorisierungscode. Keine komplexe Zugriffskontrolllogik. Es funktioniert einfach.
Praxisbeispiel
Gehen wir beide Benutzerszenarien durch, um zu sehen, wie derselbe API-Aufruf unterschiedliche Ergebnisse liefert. Stellen Sie sich vor, Sie haben Ihr System mit Aidbox, verbunden mit Keycloak, eingerichtet, und sowohl Dr. Sarah (die Ärztin) als auch Mike (der Labortechniker) nutzen dieselbe Anwendung.
Im System gibt es zwei Observation-Ressourcen:
- Hämoglobin – eine Laborbeobachtung mit dem Status „final"
- Blutdruck – eine Vitalzeichen-Beobachtung
Beide Benutzer greifen auf denselben Endpunkt zu: GET /fhir/Observation
Aber Aidbox gibt je nach anfragender Person unterschiedliche Antworten zurück.
Test 1: Ärztlicher Zugriff (Vollzugriff)
Anmeldedaten:
Username: physician
Password: password
API-Aufruf:
GET /fhir/Observation
Authorization: Bearer <physician_token>
Token-Scopes:
user/Patient.rs user/Encounter.rs user/Observation.rs
Ergebnis: Die Ärztin sieht beide Observations:
- Hämoglobin (Labor, final)
- Blutdruck (Vitalzeichen)
Der Scope user/Observation.rs gewährt uneingeschränkten Zugriff auf alle Observation-Ressourcen.
Test 2: Zugriff des Labortechnikers (eingeschränkter Zugriff)
Anmeldedaten:
Username: lab_technician
Password: password
API-Aufruf:
GET /fhir/Observation
Authorization: Bearer <lab_technician_token>
Token-Scopes:
user/Patient.rs
user/Observation.rs?category=laboratory&status=final
Ergebnis: Der Labortechniker sieht nur eine Observation:
- Hämoglobin (Labor, final)
Die Blutdruck-Observation wird herausgefiltert, da sie nicht den Scope-Anforderungen entspricht:
- Ihre Kategorie ist „vital-signs" (nicht „laboratory")
- Der Scope erfordert ausdrücklich
category=laboratory&status=final
Gleicher Endpunkt, gleicher Code, unterschiedliche Ergebnisse je nach anfragender Person. Keine benutzerdefinierte Filterlogik erforderlich.
Selbst ausprobieren
Möchten Sie dies in der Praxis sehen? Das vollständige Beispiel ist bereit, mit Docker ausgeführt zu werden.
Voraussetzungen: Docker und Docker Compose müssen installiert sein
Schnellstart:
- Klonen Sie das Repository und navigieren Sie zum Beispiel:
cd aidbox-features/smart-keycloak-roles
- Starten Sie alle Dienste:
docker compose up --build
-
Aidbox initialisieren: Navigieren Sie zu http://localhost:8080 und schließen Sie die Aidbox-Initialisierung ab.
-
Demo-Anwendung öffnen: Navigieren Sie zu http://localhost:3000.
-
Beide Benutzerrollen testen:
Melden Sie sich als physician/password an – sehen Sie alle Observations
- Klicken Sie auf „Start Over" und melden Sie sich als
lab_technician/passwordan – sehen Sie nur Laborbefunde
Die Demo-Anwendung zeigt nebeneinander, auf was jeder Benutzer zugreifen kann, und macht die Unterschiede in der Zugriffskontrolle unmittelbar sichtbar.
Wesentliche Erkenntnisse
Dieser Ansatz bietet mehrere bedeutende Vorteile:
1. Kein benutzerdefinierter Autorisierungscode Ihre Anwendung muss Rollen weder verstehen noch Filterlogik implementieren. Aidbox erledigt dies automatisch auf Basis von SMART-Scopes.
2. Zentrale Zugriffskontrolle Alle Rollendefinitionen befinden sich in Ihrem Identity Provider (Keycloak). Ändern Sie die Berechtigungen einer Rolle an einer Stelle, und die Änderung gilt überall.
3. Standardbasiert Basiert auf SMART on FHIR V2, einem etablierten Standard für die Interoperabilität im Gesundheitswesen. Keine proprietären Lösungen oder Vendor-Lock-in.
4. Feingranulare Kontrolle Abfrageparameter-Einschränkungen (?category=laboratory&status=final) ermöglichen präzise Zugriffskontrolle ohne komplexe benutzerdefinierte Regeln.
5. Einfach erweiterbar Benötigen Sie eine neue Rolle? Erstellen Sie in Keycloak eine Composite-Rolle, die die entsprechenden Basisrollen kombiniert. Keine Codeänderungen erforderlich.
Weitere Informationen:
Fazit
Feingranulare Zugriffskontrolle für FHIR-Ressourcen muss nicht kompliziert sein. Durch die Kombination von SMART on FHIR V2-Scopes, dem Composite-Rollen-System von Keycloak und der automatischen Scope-Durchsetzung durch Aidbox können Sie eine ausgefeilte RBAC implementieren, ohne benutzerdefinierten Autorisierungscode zu schreiben.
Das Ergebnis: sicherere Anwendungen, einfachere Wartung und bessere Ausrichtung an Healthcare-Interoperabilitätsstandards.
Sind Sie bereit, rollenbasierte Zugriffskontrolle in Ihrer FHIR-Anwendung zu implementieren? Starten Sie mit dem Beispiel-Repository und passen Sie die Rollen an Ihren spezifischen Anwendungsfall an.





