Teams ausgehend WebHooks

Neben den Teams eingehenden WebHooks geht es natürlich auch in die Gegenrichtung. Dazu müssen Sie einen WebService erstellen und über eine öffentlich erreichbare URL publizieren, die dann Teams bei einer Änderung im Kanal aufruft. Dies ist neben der Entwicklung eines Bot eine einfache Möglichkeit Informationen aus einem Kanal zu erhalten und sogar umgehend darauf zu reagieren. Die Antwort auf den HTTP-Request erscheint direkt in der Konversation zur Anfrage. Allerdings muss ihr Service diese Antwort innerhalb von 5 Sekunden zurück senden. Zudem hat der Service keine Möglichkeit proaktiv in einem Kanal aktiv zu werden und er kann zwar Cards zurücksenden, die aber keine Action-Buttons enthalten dürfen. Voraussetzung ist natürlich, dass ihr Service erreichbar ist. Es gibt hier nach meinem Wissen kein Queuing oder Retry-Versuche. Wenn ihr Service offline ist, dann verpassen Sie entsprechende Meldungen

Solche Einschränkungen sind sicher auch als Schutz gedacht. Denn missbrauch ist schon denkbar, dass jemand einen Office 365 Test-Tenant nutzt und über die URL eines Outgoing Webhook eine ganz fremde Seite angreift oder versucht die Teams-Plattform zu überlasten. Bei Exchange gab es da über den Jahreswechsel 2018/2019 ja auch einen Issue, dass EWS Callback-URls sogar als Sicherheitslücke genutzt werden konnten.

Die Einrichtung kann wieder der Besitzer eines Teams selbst machen. Sie gehen wieder in das Team und dann auf Apps und finden ganz unten fast unsichtbar am Rand den Punkt "Ausgehenden Webhook erstellen"

Im ersten Dialog ist die URL der wichtigste Punkt. Name und Beschreibung dienen eher der Dokumentation:

Der Link mit weiteren Informationen geht nur auf "https://teams.microsoft.com/_". Im nächsten Dialog liefert ihnen Teams dann quasi das "Kennwort", mit dem sich Teams gegenüber ihrer Webseite ausweist.

Der Link hier geht auf https://aka.ms/microsoftteamscustombotssecurity/, welcher im Sep 2019 aber auch nur auf https://developer.microsoft.com/en-us/microsoft-teams weiter geleitet hat. Dieses Token sollten Sie sich merken, da es später nicht mehr sichtbar ist. Teams sendet es als Authentifizierung mit jedem Request an ihre URL und ihr Applikation sollte dieses Token natürlich prüfen.

Technisch liefert Teams einen HMAC-Code im Header des Requests. Um diesen selbst zu errechnen, müssen Sie den Body in ein UTF8 byte array wandeln und einen SHA256 HMAC Hash mit dem Security Token erstellen und das Ergebnis vergleichen. Wenn das Ergebnis stimmt, dann kam der Request von Teams. Das Security Token geht also nie über die Leitung. Dennoch sollten Sie die Verbindung per HTTP verschlüseln.

Auch ein ausgehender Webhook erscheint dann wieder in der App-Übersicht des Team.

Ich kann hier aber nur Namen, URL und Beschreibung ändern aber habe keinen Zugriff mehr aus das Secret.

Der ausgehende Webhook wird also nicht pro Kanal sondern für das komplette Team gebunden. Der Webhook erscheint nun auch als mögliche Empfänger und genau das ist der Trigger.

Ich kann über den Weg eine Message in jedem beliebigen Kanal über eine "@Erwähnung" (Mentioning) auch dem Webhook mitteilen. Ich habe dazu einen ganz trivialen Webhook-Responder in PHP geschrieben und temporär auf der MSXFAQ hinterlegt:

<?php
// Header setzen
header_remove();
http_response_code(200);
header("Cache-Control: no-transform,public,max-age=300,s-maxage=900");
header('Content-Type: application/json');
header('Status: 200');

// JSON Body ausgeben
echo '
{
    "type": "message",
    "text": "Webhook received"
}';
?>

Das PHP-Script prüft nun natürlich weder den HMAC Header noch macht es einen SHA256 Hash und es wertet schon gar nicht die Daten im Request aus um entsprechend sinnvoll zu reagieren. Es ist einfach nur ein Sample zur Anzeige der Antwort in Teams. So sieht dann die Antwort aus

Sollte der WebHook nicht reagieren, dann bekomme ich das in wenigen Sekunden mit:

Ein Webhook ist also nicht so eng eingebunden wie ein Teams Bot aber für die ein oder andere Funktion durchaus ausreichend und viel einfacher zu implementieren. Wer aber eine engere Integration möchte, muss sich eher einem BOT zuwenden.

Ein Beispiel dazu habe ich aber nicht entwickelt. Sicher könnte ich per PowerShell einfach einen Webserver betreiben, aber er muss ja von Teams aus dem Internet erreichbar sein. Dazu benötigt er einen DNS-Namen, eine IP-Adresse und ein Zertifikat. Solche Dienste werden daher eher als Service oder VMs in Azure gehostet oder im eigenen RZ mit Firewall und Loadbalancer hochverfügbar bereitgestellt und sind doch sehr spezifisch.

Meine Entwickler-Kollegen bei Net at Work können ihnen aber hier gerne bei der Analyse ihrer Anforderungen und der Entwicklung und Bereitstellung solchen Lösungen helfen.

Weitere Links