Benutzer-Authentifizierung
Der Apptiva Klar Website Messenger unterstützt zwei getrennte Verfahren, die unabhängig voneinander oder gemeinsam aktiviert werden können:
- Identity-Provider-Authentifizierung: Der Benutzer authentifiziert sich über einen konfigurierten externen Identity Provider. Die aktuelle Implementierung verwendet SAML, beispielsweise mit Microsoft Entra ID.
- Host-Benutzeridentifikation: Die einbettende Host-Anwendung liefert bei Bedarf ein kurzlebiges Token für den aktuell eingeloggten Benutzer. Der Website Messenger löst dieses Token serverseitig über den konfigurierten Identifikationsdienst ein.
Identity-Provider-Authentifizierung
Die Identity-Provider-Authentifizierung wird über die Property auth konfiguriert. Ist sie aktiviert, wird beim Laden des Chats zunächst der Startbildschirm angezeigt. Nach einem Klick auf „Chat starten“ öffnet sich ein neues Anmeldefenster.
Der Client erzeugt dafür ein kurzlebiges identityProviderLoginRequestToken. Dieses Token dient nur dazu, die Login-Anfrage dem ursprünglichen Browser-Socket zuzuordnen. Nach erfolgreicher Anmeldung stellt der Server ein kurzlebiges identityProviderLoginToken aus und übermittelt es an den Client.
Der Client sendet dieses Token anschliessend zusammen mit dem start-chat-Request an den Server. Erst wenn das Backend das Token erfolgreich validiert und die Session erstellt hat, wird der Chat freigeschaltet. Während dieser Prüfung bleibt der Startbildschirm sichtbar und zeigt einen Ladeindikator. Die Chat-Eingabe wird erst nach der Serverbestätigung chat-started angezeigt.
Host-Benutzeridentifikation
Die Host-Benutzeridentifikation wird über die Property identifyHostUser konfiguriert. Sie ist für Webseiten gedacht, auf denen der Benutzer bereits angemeldet ist und der Website Messenger diese Identität übernehmen soll.
Beim Start eines Chats fordert der iframe die Host-Anwendung über das Event ON_HOST_USER_IDENTIFICATION_TOKEN_REQUESTED auf, ein kurzlebiges Token bereitzustellen. Die Host-Anwendung erzeugt oder bezieht das Token über ihre eigene Session und übergibt es anschliessend mit:
window.chatbot.provideHostUserIdentificationToken(token);
Beispiel: Reaktion der Host-Anwendung
Der Handler muss registriert werden, bevor ein Benutzer den Chat startet. Die Host-Anwendung ruft dabei einen eigenen, geschützten Endpunkt auf. Durch credentials: 'include' wird die bestehende Session der Host-Anwendung an diesen Endpunkt übermittelt:
<script>
window.addEventListener("DOMContentLoaded", () => {
window.chatbot.subscribe(
"ON_HOST_USER_IDENTIFICATION_TOKEN_REQUESTED",
async () => {
try {
const response = await fetch("/api/chat/identification-token", {
method: "POST",
credentials: "include",
headers: {
Accept: "application/json",
},
});
if (!response.ok) {
console.warn("Host user identification token could not be created");
return;
}
const { token } = await response.json();
if (typeof token !== "string" || token.length === 0) {
console.warn(
"Host user identification response contained no token",
);
return;
}
window.chatbot.provideHostUserIdentificationToken(token);
} catch (error) {
console.warn("Host user identification request failed", error);
}
},
);
});
</script>
Der Endpunkt /api/chat/identification-token gehört zur Host-Anwendung. Er prüft die dortige Benutzer-Session und stellt nur dann ein kurzlebiges, signiertes Token aus.
Das Token selbst wird nicht als URL-Parameter an den Chatbot übergeben. Der iframe sendet es über eine origin-validierte postMessage-Verbindung an den Chatbot. Der Server übergibt es an den in identifyHostUser konfigurierten Callback. Der Callback muss die Benutzerinformationen serverseitig auflösen und zurückgeben:
const webclientProps = {
identifyHostUser: async (token: string) => {
const response = await resolveUserIdentificationToken(token);
if (response.status === 404) {
return null;
}
if (!response.ok) {
throw new Error("Host user identification failed");
}
return await response.json();
},
};
Beispiel für eine erfolgreiche Response des Identifikationsdienstes:
{
"userId": "user-123",
"firstName": "Max",
"lastName": "Muster",
"email": "max.muster@example.com",
"payload": {
"department": "Support"
}
}
Bei einem erfolgreichen Ergebnis ist ausschliesslich userId erforderlich. Diese stabile Benutzer-ID wird im Benutzerprofil der Session gespeichert und ermöglicht die eindeutige Zuordnung des Chats zum Benutzer. Sie ist nicht mit der technischen Chat-sessionId gleichzusetzen. Optional können firstName, lastName, email und zusätzliche Daten im payload mitgegeben werden. Vorhandene optionale Angaben werden in die Session übernommen und können zur Personalisierung oder für nachgelagerte Middleware verwendet werden.
Bei einem unbekannten oder abgelaufenen Token muss der Callback null zurückgeben. Der Chatbot eröffnet dann keine Session und zeigt wieder den Startbildschirm mit einer neutralen Fehlermeldung an.
Kombination beider Verfahren
Beide Verfahren können gleichzeitig aktiviert werden. In diesem Fall läuft der Ablauf wie folgt:
- Der Benutzer startet den Chat.
- Die Host-Anwendung stellt ein
hostUserIdentificationTokenbereit. - Der Benutzer authentifiziert sich im Fenster des Identity Providers.
- Der Client sendet
identityProviderLoginTokenundhostUserIdentificationTokengemeinsam an den Server. - Der Server validiert beide Informationen und erstellt die Chat-Session.
- Erst danach wird der Chat mit
chat-startedfreigeschaltet.
Die beiden Token haben unterschiedliche Aufgaben und dürfen nicht verwechselt werden:
| Token | Zweck |
|---|---|
identityProviderLoginRequestToken | Zuordnung einer Login-Anfrage zum Browser-Socket |
identityProviderLoginToken | Kurzlebiges Token, das nach erfolgreicher Anmeldung beim Identity Provider vom Server als gültige Authentifizierung akzeptiert wird und die Session-Erstellung freischaltet |
hostUserIdentificationToken | Kurzlebiges Token der einbettenden Host-Anwendung zur Benutzeridentifikation |
Verhalten beim Neuladen
Ein Reload des Browsers soll einen eingebetteten Chat nicht unnötig zurücksetzen. Anonyme Sessions können über ihre gespeicherte Session-ID fortgesetzt werden. Bei aktivierter Host-Benutzeridentifikation werden Authentifizierungstokens jedoch nicht gespeichert. Nach dem Wiederaufbau der Socket-Verbindung fordert der Client deshalb ein neues hostUserIdentificationToken an und validiert die Session erneut.
Auch identityProviderLoginToken und identityProviderLoginRequestToken werden nicht im Local Storage gespeichert. Die Session wird erst nach einer erneuten erfolgreichen Validierung als bereit markiert. Schlägt die Re-Authentifizierung fehl, wird der Startbildschirm angezeigt.
Fehlerbehandlung
Bei ungültigen, unbekannten oder abgelaufenen Tokens wird keine Chat-Session eröffnet. Der Server meldet den Fehler über auth-failed; der Client:
- beendet den laufenden Startversuch,
- verwirft die kurzlebigen Tokens,
- zeigt den Startbildschirm erneut an,
- zeigt eine neutrale Meldung an: „Anmeldung nicht erfolgreich. Bitte erneut versuchen.“
Technische Details des Identifikationsdienstes oder konkrete Tokenwerte werden nicht an den Browser weitergegeben. Unerwartete Fehler werden ausschliesslich serverseitig protokolliert.
Sicherheitshinweise
- Tokens müssen kurzlebig und signiert sein.
- Der Identifikationsdienst sollte Tokens zusätzlich über eine eindeutige
jtigegen Replay schützen. - Tokens dürfen nicht in URLs, Local Storage, Session Storage oder Analytics-Daten abgelegt werden.
allowedEmbedOriginsmuss auf dem Messenger-Server korrekt konfiguriert sein.- Die Host-Webseite muss den Handler für
ON_HOST_USER_IDENTIFICATION_TOKEN_REQUESTEDregistrieren, bevor der Benutzer den Chat startet. - Der Identifikationscallback muss die Antwort des externen Dienstes serverseitig validieren und darf keine ungeprüften Benutzerdaten in die Session übernehmen.