# Externer Autorisierungsdienst

Source: https://www.veeting.com/de/developer-documentation/external-meeting-authorization-service

## Übersicht

Sie können den Zugang zu einem Meeting auf verschiedene Arten einschränken. Bei einer davon entscheidet ein Dienst von Ihnen, wer beitreten darf. So gelten für das Meeting genau die Regeln, die Ihre Systeme ohnehin durchsetzen, etwa ein Kundenportal, eine Patientenakte oder ein Falldossier.

Diese Seite zeigt Ihnen, wie Sie diesen Dienst bauen.

## Verwendung mit einem KI-Assistenten

Viele Integrationen entstehen heute mit einem KI-Assistenten. Arbeiten Sie ebenso, dann kopieren Sie den folgenden Text in Ihren Assistenten und schreiben Sie einen Satz dazu, was Sie bauen möchten.

Der Text schickt den Assistenten zuerst auf diese Seite und warnt ihn vor den wenigen Dingen, die er sonst gerne falsch macht.

```text
Lies zuerst diese Seite, bevor Du Code schreibst:
https://www.veeting.com/de/developer-documentation/external-meeting-authorization-service

Sie beschreibt, wie ich Teilnehmer mit meinem eigenen Dienst
autorisiere. Halte Dich an diese fünf Regeln:

1. Der Tokentausch läuft von Server zu Server. Die URL enthält ein
   gemeinsames Geheimnis. Rufe sie also nie aus einem Browser auf
   und logge sie nie.
2. Prüfe beim Tausch responseCode 0, nicht nur HTTP 200.
3. Leite zurück auf /meeting/<MEETING-TOKEN>/join und hänge
   meetingAccessToken als Query-Parameter an.
4. Der Tausch braucht die 24-stellige meetingId, die Rückleitung
   die meetingToken mit Bindestrichen. Verwechsle die beiden
   nicht.
5. Der Request-Token belegt, dass die Plattform die Person zu mir
   geschickt hat. Er authentifiziert sie NICHT. Das muss ich
   selbst tun.

Was ich bauen möchte:
```

## Wie der Austausch funktioniert

Der Ablauf ist eine dreistufige Weiterleitung und ähnlich aufgebaut wie OAuth.

1. Ein Teilnehmer öffnet ein eingeschränktes Meeting. Die Plattform erzeugt einen **Request-Token** und leitet den Browser mit diesem Token zu Ihrem Dienst.
2. Ihr Dienst authentifiziert die Person auf Ihre Weise und entscheidet, ob sie beitreten darf.
3. Darf sie beitreten, ruft Ihr Dienst uns von Server zu Server auf und tauscht den Request-Token gegen einen **Access-Token**.
4. Ihr Dienst leitet den Browser mit dem Access-Token zurück zum Meeting. Dieser Token öffnet der Browsersession den Zugang.

![Ein Browser öffnet ein geschütztes Meeting, wird mit einem Request Token an Ihren Dienst weitergeleitet, Ihr Dienst authentifiziert die Person und tauscht das Token gegen ein Access Token, dann leitet er den Browser zurück zum Meeting](/assets/img/documentation/external-meeting-authorization-service-workflow.de.svg)

<!-- Source of the diagram above. Regenerate with local-scripts/diagrams/render.sh -->
```mermaid
sequenceDiagram
    autonumber
    participant B as Browser
    participant V as Web-Meeting-Server
    participant S as Ihr Dienst
    B->>V: Öffnet ein geschütztes Meeting
    V-->>B: Weiterleitung, mit einem Request Token
    B->>S: Kommt mit dem Request Token an
    Note over S: Authentifiziert die Person<br/>und entscheidet
    S->>V: Tauscht das Request Token<br/>(Server zu Server)
    V-->>S: Access Token
    S-->>B: Weiterleitung zurück zum Meeting,<br/>mit dem Access Token
    B->>V: Betritt das Meeting mit dem Access Token
```

Der Request-Token belegt, dass die Plattform die Person zu Ihnen geschickt hat. Der Access-Token belegt, dass Sie sie zurückgeschickt haben.

## Schritt 1: die Weiterleitung entgegennehmen

Bauen Sie einen Endpunkt, der auf `HTTP GET` antwortet. Dorthin leiten wir den Browser, und wir hängen mindestens diese Query-Parameter an:

| Parameter | Beschreibung |
| --- | --- |
| hostname | Der Hostname der Meeting-Plattform, zum Beispiel `meeting.example.org` |
| meetingId | Die 24-stellige Meeting-ID, zum Beispiel `5f521a93c20ff6721fbb6a6c` |
| meetingToken | Die Meetingnummer mit Bindestrichen, zum Beispiel `0000-0000-0000-0000` |
| requestToken | Ein langer, zufälliger String, der nur für dieses Meeting gilt |

Wir können weitere Parameter anhängen. Lesen Sie die Parameter, die Sie brauchen, deshalb über ihren Namen aus und nicht über ihre Position.

Lautet Ihr Endpunkt `https://external.example.org/auth`, kommt der Browser hier an:

```text
https://external.example.org/auth?hostname=webmeeting.example.com&meetingId=5f521a93c20ff6721fbb6a6c&meetingToken=8320-2640-2482-3499&requestToken=dedf1722-661f-4004-9aaf-d3e56c498859-a27fd10f-b697-4c83-bca0-cb764cfd6c43
```

## Schritt 2: den Request-Token eintauschen

Sobald Sie entschieden haben, dass die Person beitreten darf, rufen Sie uns auf und tauschen den Request-Token gegen einen Access-Token:

```text
GET https://<HOSTNAME>/api/v6/meeting-room/auth/<SECRET>/access-token/<MEETING-ID>/<REQUEST-TOKEN>
```

| Platzhalter | Wert |
| --- | --- |
| HOSTNAME | Der `hostname` aus der Weiterleitung |
| SECRET | Das gemeinsame Geheimnis, das Sie hinterlegt haben, siehe unten |
| MEETING-ID | Die 24-stellige `meetingId` aus der Weiterleitung |
| REQUEST-TOKEN | Der `requestToken` aus der Weiterleitung |

Wir prüfen, ob wir den Request-Token für dieses Meeting ausgestellt haben. Stimmt alles, antworten wir so:

```json
{
  "responseCode": 0,
  "data": {
    "meetingId": "5f521a93c20ff6721fbb6a6c",
    "accessToken": "81430667-540e-4755-b32a-b5c51f704c7b-03526573-1494-48fb-a648-e80073275976"
  }
}
```

Dieser Aufruf folgt den üblichen Konventionen der REST API. **Prüfen Sie deshalb `responseCode` und nicht nur den HTTP-Status.** Den Token lesen Sie aus `data.accessToken`. Wie der Response-Wrapper aufgebaut ist, lesen Sie unter [REST APIs](/de/developer-documentation/api-usage).

> **Dieser Aufruf führt Ihr Geheimnis in der URL mit.** Rufen Sie ihn von Server zu Server auf, nie aus dem Browser. Und loggen Sie die vollständige URL nirgends.

## Schritt 3: zurück zum Meeting leiten

Schicken Sie den Browser mit dem Access-Token zum Meetingraum:

```text
https://<HOSTNAME>/meeting/<MEETING-TOKEN>/join?meetingAccessToken=<ACCESS-TOKEN>
```

| Platzhalter | Wert |
| --- | --- |
| HOSTNAME | Der `hostname` aus der Weiterleitung |
| MEETING-TOKEN | Die Meetingnummer **mit Bindestrichen** aus der Weiterleitung, nicht die 24-stellige |
| ACCESS-TOKEN | Der `accessToken`, den Sie soeben erhalten haben |

Hängen Sie weitere [Query-Parameter](/de/developer-documentation/query-parameters) an, um der Person die Ankunft zu erleichtern. Am ehesten lohnen sich jene Werte, die Sie aus der eben erfolgten Authentifizierung schon kennen:

```text
https://<HOSTNAME>/meeting/<MEETING-TOKEN>/join?meetingAccessToken=<ACCESS-TOKEN>&participantName=<NAME>&participantEmail=<EMAIL>
```

## Die Plattform konfigurieren

Gehen Sie zu **Platform Settings**, dann **System Configuration**, dann **Meeting Room**. Wählen Sie dort als Standard-Authentifizierungsart für Meetings **External Service**. Danach erscheinen zwei Felder.

![Configuration of external meeting authorization service](/assets/img/documentation/external-meeting-authorization-service-configuration.png)

Tragen Sie die vollständige URL Ihres Endpunkts in «URL of external authentication server» ein und Ihr gewähltes Geheimnis in «API Key of external authentication server». Wir speichern das Geheimnis verschlüsselt und prüfen jeden Tokentausch dagegen.

Das Geheimnis erfinden Sie selbst. Behandeln Sie es wie ein Passwort: lang und zufällig. Gelangt es je nach aussen, wechseln Sie es.

## Eine minimale Umsetzung

```javascript
const express = require("express");
const app = express();
const port = 3000;

// Invent this yourself and configure the same value in the platform.
const SECRET = process.env.VEETING_SHARED_SECRET;

app.get("/auth", async (req, res) => {
  const { hostname, meetingId, meetingToken, requestToken } = req.query;

  // Decide here whether this person may join, using your own session,
  // directory or customer database. Redirect them away if they may not.
  if (!(await mayJoin(req, meetingId))) {
    return res.status(403).send("Not authorized to join this meeting");
  }

  // Server to server: this URL contains the shared secret.
  const url = `https://${hostname}/api/v6/meeting-room/auth/${SECRET}`
    + `/access-token/${meetingId}/${requestToken}`;

  const response = await fetch(url).then((r) => r.json());

  // HTTP 200 is not enough on its own, check responseCode too.
  if (response.responseCode !== 0) {
    return res.status(502).send("Could not obtain an access token");
  }

  const accessToken = response.data.accessToken;

  res.redirect(`https://${hostname}/meeting/${meetingToken}/join`
    + `?meetingAccessToken=${encodeURIComponent(accessToken)}`);
});

app.listen(port);
```

## Häufige Fehler

- Auf den falschen Pfad weiterleiten. Der Meetingraum liegt unter `/meeting/<MEETING-TOKEN>/join`.
- Bei der Rückleitung die 24-stellige `meetingId` verwenden. Dort gehört die `meetingToken` mit Bindestrichen hin, beim Tokentausch ist es genau umgekehrt.
- Beim Tokentausch nur den HTTP-Status prüfen und `responseCode` übersehen.
- Den Tausch-Endpunkt aus dem Browser aufrufen und so Ihr Geheimnis preisgeben.
- Die Tausch-URL loggen und so das Geheimnis ebenfalls preisgeben.
- Die Person an Ihrem Endpunkt durchwinken, ohne sie wirklich zu authentifizieren. Der Request-Token belegt die Herkunft, nicht die Identität.

---

## Die übrige Dokumentation

- [Custom Tools – eigene Widgets im Meetingraum](https://www.veeting.com/de/developer-documentation/custom-tools)
- [iFrame und Web Komponenten](https://www.veeting.com/de/developer-documentation/iframe-and-web-components)
- [JavaScript APIs](https://www.veeting.com/de/developer-documentation/javascript-apis)
- [JavaScript und Typescript APIs](https://www.veeting.com/de/veeting-blocks/apis)
- [Komponenten](https://www.veeting.com/de/veeting-blocks/components)
- [Kontrolle über die Videodarstellung](https://www.veeting.com/de/developer-documentation/video-display-calculator)
- [Parameter in der URL](https://www.veeting.com/de/developer-documentation/query-parameters)
- [Veeting Blocks - Übersicht](https://www.veeting.com/de/veeting-blocks/introduction)
- [Veeting Rooms REST APIs](https://www.veeting.com/de/developer-documentation/api-usage)
- [Webhooks](https://www.veeting.com/de/developer-documentation/web-hooks)

Alles in einer Datei: https://www.veeting.com/llms-full.txt
