# Wie man Patienteneinwilligung mit SMART on FHIR implementiert

> Tutorial: SMART on FHIR mit OAuth 2.1 und PKCE Schritt für Schritt — Discovery, App-Registrierung, Einwilligungsbildschirm, Token-Austausch, durchgesetzte Scopes, Refresh-Rotation und Widerruf — und was Anpheros implementiert.

Source: https://developers.anpheros.com/de/guides/smart-on-fhir-backend

**SMART on FHIR ist der Standardweg, wie eine Anwendung die Erlaubnis einer Person erhält, auf deren FHIR-Datensatz zuzugreifen: OAuth 2.1 mit PKCE für die Autorisierung, Scopes, die genau angeben, was gelesen oder geschrieben werden darf, und ein Discovery-Dokument, das der Anwendung mitteilt, wohin sie gehen soll.** Dieses Tutorial durchläuft den gesamten Ablauf gegen Anpheros, Schritt für Schritt mit `curl`: Discovery, Registrierung einer Anwendung, Weiterleitung der Person zum Einwilligungsbildschirm, Austausch des Codes, Aufruf der API innerhalb der gewährten Scopes, Refresh und was passiert, wenn die Person den Zugriff widerruft. Anpheros ist das SMART on FHIR Backend: Es hostet den Autorisierungsserver, den Einwilligungsbildschirm und den FHIR R4 Server, sodass Sie keine eigene Login- oder Einwilligungs-UI schreiben müssen.

## Warum Einwilligung und nicht nur ein API-Schlüssel

Ein API-Schlüssel erreicht die Patienten, die Ihr Projekt erstellt hat. Die vorhandenen Aufzeichnungen einer Person (ihre eigenen Daten, gesammelt von anderen Apps, Kliniken und Laboren) kann sie selbst teilen. Mit SMART on FHIR:

- sieht die Person in ihrer Sprache, welche Anwendung fragt, was sie lesen oder schreiben möchte, zu welchem Zweck und wie lange;
- Ihre Anwendung erhält nur diese Ressourcentypen und Aktionen, und nur für diesen einen Datensatz;
- jeder Zugriff wird protokolliert und ist für die Person sichtbar, die ihn jederzeit widerrufen kann;
- die Erlaubnis wird auch als FHIR `Consent` Ressource gespeichert.

Das zugrunde liegende Modell wird in [Healthcare API mit Patienteneinwilligung](https://developers.anpheros.com/de/guides/healthcare-api-patient-consent) und [Einwilligungs- und Zugriffsmodell](https://developers.anpheros.com/de/guides/consent) beschrieben.

## Schritt 1: Discovery

```bash
curl https://platform.anpheros.com/fhir/R4/.well-known/smart-configuration
```

Die Antwort listet die Endpunkte auf und was der Server unterstützt (gekürzt):

```json
{"issuer": "https://platform.anpheros.com",
 "authorization_endpoint": "https://platform.anpheros.com/oauth/authorize",
 "token_endpoint": "https://platform.anpheros.com/oauth/token",
 "revocation_endpoint": "https://platform.anpheros.com/oauth/revoke",
 "code_challenge_methods_supported": ["S256"],
 "scopes_supported": ["patient/*.rs", "patient/Patient.r", "patient/Observation.rs", "patient/Observation.rs?category=laboratory",
                      "patient/Observation.rs?category=vital-signs", "patient/Observation.c", "patient/Condition.rs",
                      "patient/MedicationStatement.rs", "patient/DocumentReference.rs", "patient/AllergyIntolerance.rs",
                      "offline_access", "launch/patient", "openid", "fhirUser"],
 "capabilities": ["launch-standalone", "client-public", "client-confidential-symmetric", "permission-patient",
                  "permission-offline", "context-standalone-patient", "sso-openid-connect"]}
```

SMART-Clientbibliotheken lesen dieses Dokument und benötigen keine weitere Konfiguration.

## Schritt 2: Registrieren Sie Ihre Anwendung

Öffnen Sie in Ihrem [Dashboard](https://platform.anpheros.com/dashboard/) Ihr Projekt und fügen Sie eine Anwendung mit ihrer Redirect URI hinzu. Oder über die Admin API:

```bash
curl -X POST https://platform.anpheros.com/admin/projects/$PROJECT/applications \
     -H "Authorization: Bearer $FIREBASE_ID_TOKEN" -H "Content-Type: application/json" -d '{
  "name": "CardioAI", "client_type": "public",
  "redirect_uris": ["https://cardio.example/callback"],
  "purpose": "cardiology follow-up", "privacy_url": "https://cardio.example/privacy"
}'
```

```json
{"id": "app_…", "name": "CardioAI", "client_type": "public", "client_id": "client_Hg6CknNkYlMgN190", "client_secret": null,
 "redirect_uris": ["https://cardio.example/callback"], "purpose": "cardiology follow-up", "status": "active", …}
```

Verwenden Sie `public` für mobile und Browser-Apps, die kein Secret speichern können und auf PKCE angewiesen sind. Verwenden Sie `confidential` für einen Server; dessen `client_secret` wird einmal angezeigt. Der Name, der Zweck und der Link zur Datenschutzerklärung sind das, was die Person auf dem Zustimmungsbildschirm sieht.

## Schritt 3: Senden Sie die Person zum Zustimmungsbildschirm

Erstellen Sie ein PKCE-Paar. Der Verifier bleibt bei Ihnen; nur sein Hash wird übertragen:

```bash
VERIFIER=$(openssl rand -base64 64 | tr -d '=+/\n' | cut -c1-64)
CHALLENGE=$(printf %s "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
```

Öffnen Sie dann diese Adresse im Browser der Person (Zeilenumbrüche zur besseren Lesbarkeit hinzugefügt):

```
https://platform.anpheros.com/oauth/authorize?response_type=code
  &client_id=client_Hg6CknNkYlMgN190
  &redirect_uri=https://cardio.example/callback
  &scope=openid fhirUser patient/Observation.rs?category=laboratory patient/Condition.rs offline_access
  &state=8c1e…               ← a random value you check on return
  &code_challenge=$CHALLENGE&code_challenge_method=S256
  &purpose=treatment&lang=en
```

Fragen Sie nur nach dem Nötigsten. Diese Anwendung liest Laborergebnisse und Diagnosen, nichts weiter. `offline_access` gibt ein Refresh-Token, sodass die Person nicht alle 30 Minuten erneut zustimmen muss.

Die Person meldet sich bei Anpheros an, liest die Anfrage in Klartext, wählt aus, welche Aufzeichnung sie teilen möchte (ihre eigene, die eines Familienmitglieds, für das sie sorgt, oder die, die Ihre App für sie erstellt hat) und wie lange der Zugriff dauern soll, und erlaubt oder verweigert dann. Sie kehrt zu Ihrer Redirect URI zurück:

```
https://cardio.example/callback?code=…&state=8c1e…
```

Überprüfen Sie, ob `state` der Wert ist, den Sie zuvor gesendet haben, bevor Sie den Code verwenden.

## Schritt 4: Code gegen Tokens austauschen

```bash
curl -X POST https://platform.anpheros.com/oauth/token \
  -d grant_type=authorization_code -d client_id=client_Hg6CknNkYlMgN190 \
  -d code=$CODE -d code_verifier=$VERIFIER -d redirect_uri=https://cardio.example/callback
```

```json
{"access_token": "at_…", "token_type": "Bearer", "expires_in": 1800,
 "scope": "patient/Observation.rs?category=laboratory patient/Condition.rs openid fhirUser offline_access",
 "patient": "82bfd321-6a4d-4aea-943a-a62f4d81d419", "grant_id": "grant_…",
 "id_token": "eyJ…", "refresh_token": "rt_…"}
```

- `scope` listet auf, was gewährt wurde. Behalten Sie dies mit den Tokens bei und zeigen Sie nur die abgedeckten Funktionen an.
- `patient` ist die ID des Datensatzes für Ihre Anwendung. Sie ist paarweise: Eine andere Anwendung sieht dieselbe Person unter einer anderen ID.
- `id_token` ist ein OpenID Connect-Token, dessen `fhirUser`-Claim die Patientenressource benennt.
- Der Code funktioniert einmal und nur mit dem passenden `code_verifier`.

## Schritt 5: API innerhalb der Scopes aufrufen

```bash
curl "https://platform.anpheros.com/fhir/R4/Observation?patient=$PATIENT&category=laboratory" -H "Authorization: Bearer $ACCESS_TOKEN"
```

Laborergebnisse kommen wie gewohnt zurück. Fragen Sie nach etwas außerhalb der Berechtigung, wie z. B. Medikamenten:

```bash
curl "https://platform.anpheros.com/fhir/R4/MedicationStatement?patient=$PATIENT" -H "Authorization: Bearer $ACCESS_TOKEN"
```

```json
{"resourceType": "OperationOutcome", "issue": [{"severity": "error", "code": "forbidden",
  "diagnostics": "The consent behind this token does not allow 's' on MedicationStatement."}]}
```

Das ist ein `403`. Suchen innerhalb der Berechtigung werden ebenfalls gefiltert: mit `Observation.rs?category=laboratory` gibt eine Suche nach allen Beobachtungen nur Laborergebnisse zurück. Jeder andere Patient existiert für dieses Token nicht (`404`). Die REST-Ansicht (`/v1`) und die [Kontext-API](https://developers.anpheros.com/de/guides/llm-healthcare-data) wenden dieselben Scopes an.

## Schritt 6: Aktualisieren

Zugriffstoken sind 30 Minuten gültig. Aktualisierungstoken sind 30 Tage gültig und werden bei jeder Verwendung rotiert:

```bash
curl -X POST https://platform.anpheros.com/oauth/token \
  -d grant_type=refresh_token -d client_id=client_Hg6CknNkYlMgN190 -d refresh_token=$REFRESH_TOKEN
```

Sie erhalten ein neues Zugriffstoken und ein neues Aktualisierungstoken. Speichern Sie das neue sofort. Die Wiederverwendung eines alten Aktualisierungstokens wird als Diebstahl behandelt: es schlägt mit `400` fehl und widerruft die gesamte Berechtigung.

## Schritt 7: Widerruf

Die Person kann Ihren Zugriff in Anpheros jederzeit widerrufen, und Sie können ihn selbst widerrufen, z. B. wenn die Verbindung in Ihrer App getrennt wird:

```bash
curl -X POST https://platform.anpheros.com/oauth/revoke -d token=$REFRESH_TOKEN -d client_id=client_Hg6CknNkYlMgN190
```

Von da an schlägt jeder Aufruf mit dieser Berechtigung fehl `401`. Behandeln Sie dies, indem Sie der Person anzeigen, dass die Verbindung beendet wurde, und anbieten, sie erneut zu verbinden. Abonnieren Sie den `consent.revoked` [Webhook](https://developers.anpheros.com/de/guides/webhooks), um dies zu erfahren, ohne auf einen fehlgeschlagenen Aufruf warten zu müssen.

## Mit den SDKs

Die [TypeScript- und Dart-SDKs](https://developers.anpheros.com/de/guides/sdks) übernehmen für Sie die Schritte 3 bis 6: `OAuthFlow.authorizeUrl` mit einem generierten PKCE-Paar, `exchange` beim Callback und automatischem Refresh mit Rotation. Vollständige Beispiele: [How to build an AI healthcare app with a FHIR backend](https://developers.anpheros.com/de/guides/build-ai-healthcare-app) (TypeScript) und [How to build a healthcare app with Flutter](https://developers.anpheros.com/de/guides/healthcare-app-flutter) (Dart).

## Was Anpheros implementiert

| Teil von SMART | In Anpheros |
|---|---|
| Discovery | `/.well-known/smart-configuration` auf der FHIR-Basis, mit den unterstützten Endpunkten, Scopes und PKCE-Methoden |
| Launch | Standalone Launch (die Anwendung startet und fordert dann Zugriff an); EHR Launch aus einem klinischen System heraus wird nicht angeboten |
| Autorisierung | OAuth 2.1 mit PKCE erforderlich, Autorisierungscode-Flow |
| Scopes | SMART v2 Patient-Scopes, `patient/<Resource>.<cruds>` mit Kategorie-Filtern, plus `openid` und `fhirUser` |
| Identität | ein OpenID Connect `id_token`, das den Patienten als FHIR-Ressource benennt |
| Zustimmung | ein gehosteter Zustimmungsbildschirm in der Sprache des Patienten, mit der vom Patienten gewählten Dauer, gespiegelt als FHIR `Consent` |
| Tokens | 30-minütige Access Tokens, rotierende 30-Tage-Refresh Tokens, die an die Zustimmung gebunden sind, Widerruf |
| Konformität | die Capability Statement deklariert den SMART Security Service; die Gruppe "Standalone Launch" des Inferno SMART App Launch STU2 Testkits besteht 22 von 22 Tests (Lauf vom 28. September 2026); die anderen Inferno-Gruppen und Testkits wurden nicht ausgeführt |

Schreiben funktioniert genauso: Scopes (`patient/Observation.c`, `.u`, `.d`) erlauben Ihrer Anwendung, innerhalb des Datensatzes zu erstellen, zu aktualisieren oder zu löschen. Alles Geschriebene trägt Ihre Anwendung als Autor, Wiederholungen mit einem Idempotenzschlüssel duplizieren niemals eine Messung, und Löschungen sind "soft" und behalten die Historie ([Medical data API](https://developers.anpheros.com/de/guides/medical-data-api)).

## Was noch nicht vorhanden ist

- EHR-Start (die Anwendung, die aus einem Hospitalsystem mit einem Startkontext heraus geöffnet wird).
- `system/` Scopes für Backend-Dienste; Organisationen verwenden stattdessen API-Schlüssel.
- Bulk Data Export (`$export`); `$everything` für einen Patienten ist verfügbar.

Diese sind zusammen mit dem Rest in [Versioning und Deprecation](https://developers.anpheros.com/de/guides/versioning) aufgeführt, und die Capability Statement ist immer die maßgebliche Quelle.

## Häufig gestellte Fragen

### Was ist SMART on FHIR?
Ein offener Standard, der auf OAuth 2.0/2.1 und OpenID Connect aufbaut und definiert, wie eine Anwendung Zugriff auf einen FHIR-Datensatz anfordert, welche Scopes diesen Zugriff beschreiben und wie der Server seine Endpunkte bewirbt. Jede SMART-fähige Client-Bibliothek kann jeden SMART-fähigen Server verwenden.

### Benötige ich PKCE?
Ja. Anpheros erfordert PKCE mit `S256` für jeden Autorisierungscode-Flow, sowohl für öffentliche als auch für vertrauliche Clients. Es verhindert, dass ein abgefangener Autorisierungscode von jemand anderem verwendet wird.

### Was passiert, wenn die Person "Nein" sagt?
Sie kehrt zu Ihrer Redirect URI mit `error=access_denied` und Ihrem `state` zurück, aber ohne Code. Erklären Sie, was die Funktion benötigt, und lassen Sie sie es erneut versuchen. Aufrufe außerhalb einer Berechtigung beantworten immer `403`.

### Kann ein Elternteil die Zustimmung für ein Kind geben?
Ja. Auf dem Zustimmungsbildschirm kann eine Person einen Datensatz auswählen, der ihr wichtig ist, z. B. den eines Kindes, wenn dieser mit ihrem Konto verknüpft ist. Die Berechtigung gilt nur für diesen Datensatz.

## Verwandte Themen

- [Authentifizierung und OAuth](https://developers.anpheros.com/de/guides/authentication): API-Schlüssel, Tokens und deren Lebensdauer im Detail
- [Healthcare API mit Patienteneinwilligung](https://developers.anpheros.com/de/guides/healthcare-api-patient-consent): Wie sich die Einwilligung auf das Design Ihrer Anwendung auswirkt
- [Einwilligungs- und Zugriffsmodell](https://developers.anpheros.com/de/guides/consent)
- [FHIR-Plattform](https://developers.anpheros.com/de/guides/fhir)
- [Entwickeln einer Healthcare-App](https://developers.anpheros.com/de/guides/build-a-healthcare-app)
