Onlinedienste mit Microsoft Graph automatisieren (1)
Sammelstelle
von Florian Frommherz
Veröffentlicht in Ausgabe 06/2021 - PRAXIS
Microsoft Graph ist die Universal-API für alle Onlinedienste von Microsoft. Egal ob Ad-hoc-Anfragen, Automatisierung mit Skripten oder Integration für eigene oder Drittanbieterlösungen – Graph ist das passende Interface. In diesem zweiteiligen Workshop gehen wir zunächst auf Anfragen und die Rechtestruktur von Graph ein.
Graph ist der Einstiegspunkt für die Automatisierung der Microsoft-Online-Dienste. Für Exchange Online, Intune, die Sicherheitsfunktionen des Defender, das Compliance Center oder Azure AD etabliert Microsoft Graph als Universal-API. Administratoren dient die PowerShell dabei in zahlreichen Anwendungsfällen als Abstraktionsschicht, die vorgefertigte Anfragen an Graph sendet und die Resultate interpretiert, aufhübscht und dann darstellt. Mit den Modulen der Hersteller kommt der Admin dabei schon weit und was fehlt, liefert oft die Community via PowerShell Gallery nach.
Um allerdings komplexere Automatisierung zu betreiben und besondere Filterklauseln in den Anfragen und über mehrere Produkte hinweg mit Graph interagieren zu lassen, kommen Sie nicht umhin, sich mit den Eigenheiten der API zu beschäftigen. Spätestens wenn es um die Weitergabe oder den Vertrieb von Skripten, kleineren Anwendungen oder Webapps geht, die nicht nur mit dem eigenen Mandanten in der Microsoft-Cloud funktionieren, sondern universell einsatzbar sein sollen, gibt es einige Dinge zu beachten.
Graph Explorer erleichtert den Einstieg
Eine Wunderwaffe beim Einstieg in Microsoft Graph und dem Verstehen der Grundlagen ist der Graph Explorer [1], den Microsoft nicht nur Entwicklern und IT-Pros zur Verfügung stellt. Der Graph Explorer ist eine frei verfügbare Webapp, die – nach Log-on mit Anmeldeinformationen eines Test- oder Produktions-Tenants – Abfragebeispiele und freie Anfragen an Microsoft Graph für einen Tenant erlaubt. Wer Netzwerkanalysetools wie Fiddler oder Postman kennt, dem wird das Prinzip geläufig sein: Sie definieren Anfragen im Graph Explorer inklusive notwendiger Zusatzparameter, die im Bauch des Requests auf die Reise gehen. Die Antworten finden Sie dann im "Response"-Teil des Explorers, und zwar nach JSON-Standard formatiert.
Graph ist der Einstiegspunkt für die Automatisierung der Microsoft-Online-Dienste. Für Exchange Online, Intune, die Sicherheitsfunktionen des Defender, das Compliance Center oder Azure AD etabliert Microsoft Graph als Universal-API. Administratoren dient die PowerShell dabei in zahlreichen Anwendungsfällen als Abstraktionsschicht, die vorgefertigte Anfragen an Graph sendet und die Resultate interpretiert, aufhübscht und dann darstellt. Mit den Modulen der Hersteller kommt der Admin dabei schon weit und was fehlt, liefert oft die Community via PowerShell Gallery nach.
Um allerdings komplexere Automatisierung zu betreiben und besondere Filterklauseln in den Anfragen und über mehrere Produkte hinweg mit Graph interagieren zu lassen, kommen Sie nicht umhin, sich mit den Eigenheiten der API zu beschäftigen. Spätestens wenn es um die Weitergabe oder den Vertrieb von Skripten, kleineren Anwendungen oder Webapps geht, die nicht nur mit dem eigenen Mandanten in der Microsoft-Cloud funktionieren, sondern universell einsatzbar sein sollen, gibt es einige Dinge zu beachten.
Graph Explorer erleichtert den Einstieg
Eine Wunderwaffe beim Einstieg in Microsoft Graph und dem Verstehen der Grundlagen ist der Graph Explorer [1], den Microsoft nicht nur Entwicklern und IT-Pros zur Verfügung stellt. Der Graph Explorer ist eine frei verfügbare Webapp, die – nach Log-on mit Anmeldeinformationen eines Test- oder Produktions-Tenants – Abfragebeispiele und freie Anfragen an Microsoft Graph für einen Tenant erlaubt. Wer Netzwerkanalysetools wie Fiddler oder Postman kennt, dem wird das Prinzip geläufig sein: Sie definieren Anfragen im Graph Explorer inklusive notwendiger Zusatzparameter, die im Bauch des Requests auf die Reise gehen. Die Antworten finden Sie dann im "Response"-Teil des Explorers, und zwar nach JSON-Standard formatiert.
Der Explorer benötigt keine Installation, lediglich die erstmalige Einrichtung für den eigenen Benutzeraccount oder alle Benutzer des Tenants ist erforderlich. Wenn Sie den Graph Explorer starten, registrieren Sie sich zunächst mit den Anmeldedaten eines Tenants. Der blaue "Sign in to Graph Explorer"-Knopf startet den modernen Anmeldevorgang. Nutzen Sie den Graph Explorer zum ersten Mal oder wurde der Explorer noch nie im Tenant verwendet, müssen Sie vor Abschluss der Anmeldung der Nutzung zustimmen.
Das Azure Active Directory (AAD) fragt nach Zustimmung für das Sign-in zur Anwendung sowie für das oAuth2-Recht "offline_access". Je nach Einstellung im Tenant können Sie als Nicht-Admin selbst zustimmen oder müssen einen Admin um Erlaubnis bitten. Die Einstellung, die Benutzer- oder Admin-Erlaubnis einfordert, finden Sie im AAD-Portal unter "Azure Active Directory / Enterprise Applications / Consent and Permissions: User consent for applications". Sie wählen zwischen drei Möglichkeiten aus, wobei die liberalste Einstellung "Allow user content for apps" in neuen Tenants voreingestellt ist. Die Option "Do not allow user consent" erfordert, dass ein Administrator die Anwendung erlaubt, wonach Sie im Fenster "Have an admin account? Sign in with that account" klicken müssen, um als Admin die Bestätigung zu erteilen.
Erste Anfrage erstellen
Hat die Anmeldung geklappt, können Sie mit den ersten Anfragen beginnen. Am oberen Fensterrand sehen Sie mehrere Auswahloptionen, "GET", "v1.0" und ein Eingabefeld mit der URL "https://graph. microsoft.com/v1.0/me". Klicken Sie auf den Button "Run Query" ohne Modifikationen, erstellt Graph Explorer die Anfrage und zeigt das Ergebnis im unteren "Response Preview"-Fenster an. Dort sehen Sie auch eine grüne Leiste, die "OK – 200" und eine Millisekundenzahl ausweist. Die voreingestellte Anfrage richtet sich an den V1.0-Endpoint, die Anfrage beinhaltet also keine Daten oder Endpunkte aus Microsofts "Beta"-Programm. Im Detail können Sie nachvollziehen, dass Sie Daten anfragen (GET) möchten und nicht schreiben (POST), überschreiben (PATCH) oder löschen (DELETE). Zudem interessieren Sie sich für Ihr eigenes Profil in Azure AD ("me"). Der Ergebnissatz im unteren Fenster zeigt Ihnen einige Attribute und deren Feldwerte, die im AAD für den angemeldeten Benutzer existieren. Unter anderem sehen Sie Ihren im AAD hinterlegten Namen, den Jobtitel und die Bürolokation. Das Ergebnis ist ein einziges Objekt im JSON-Format.
Fügen Sie der Anfrage ein "/memberOf" an, sodass Sie Graph auf "https://graph. microsoft.com/v1.0/me/memberOf" richten, erhalten Sie ein anderes Ergebnisbild. Die Antwort enthält diesmal mehrere Objekte, per Kommata getrennt aufgelistet, und zeigt alle Gruppen, in denen Sie direkt Mitglied sind. Die Attribute der Gruppenobjekte sind überwiegend leer und mit Null beschrieben. Das liegt daran, dass Graph Explorer zwar im Kontext des angemeldeten Benutzers agieren darf, aber im Moment nur das Profil, wie im Zustimmungsbildschirm erlaubt, lesen darf. Graph Explorer – und alle anderen AAD-integrierten Anwendungen – können im Benutzerkontext nur mit APIs interagieren, zu denen der Benutzer selbst Berechtigungen hat und wenn diese durch den Benutzer oder Admin gewährt wurde.
Für weitere Zustimmungen, wie in diesem Fall für das Lesen der Gruppendetails, klicken Sie auf "Modify Permissions (Preview)". Der Graph Explorer schlägt dann mehrere Berechtigungen vor, die für diese Anfrage helfen. Für jede sehen Sie einen "Consent"-Knopf. Ob für die Berechtigung eine Adminzustimmung erforderlich ist, entnehmen Sie der Spalte "Admin Consent Required". Die möglichen Berechtigungsoptionen werden dort vorgeschlagen.
Bild 1: Mit dem Graph Explorer erstellen Sie erste Graph-Anfragen, erproben Filter- und Suchanfragen und inspizieren Ergebnisse.
Zustimmungsmodell und Berechtigungen
Bevor Anwendungen im Azure AD als Dienstkonten oder im Benutzerkontext auf Ressourcen oder APIs zugreifen können, müssen Endbenutzer oder Administratoren – je nach Konfiguration des Tenants – diesem Zugriff explizit zustimmen. Anwendungen können nicht ohne Weiteres Daten anderer Dienste abrufen oder im Benutzerkontext Daten einer Benutzer-Mailbox abfragen, selbst wenn der Benutzer die App selbst gestartet hat.
Dieser Schutzmechanismus ist Teil des OAuth2.0-Rahmenwerkes, das die Autorisierung, also die Konfiguration von "wer darf eigentlich was?", der modernen Anmeldeprotokolle beschreibt. Bevor eine Anwendung Zugriff auf Daten oder APIs erhält, muss sie einen sogenannten OAuth2Grant, also eine Erlaubnis, erhalten, die je nach Tragweite der gewünschten Berechtigung von einem Administrator getätigt werden muss.
Für diesen Artikel ist der Graph Explorer eine Anwendung, mit der wir Testbenutzer anmelden, um Anfragen an Graph zu senden. Graph ist dabei die API, die der Graph Explorer im Kontext des angemeldeten Benutzers aufrufen darf. In unserem ersten Beispiel, bei der ersten Anfrage zum Benutzerprofil des Benutzers, hatte Azure AD erstmalig nach einem Consent – also der Zustimmung des Benutzers – gefragt. Damit darf Graph Explorer im Namen des angemeldeten Benutzers die Graph-API nach dem Benutzerprofil fragen.
Die OAuth2Grants sind dabei an Scopes gebunden, für die eine Zustimmung gilt. Anfänglich war das "offline_access" und "sign-in". Fragen wir aber nach zusätzlichen Objekttypen mit Hilfe der Graph-API, müssen wir zusätzlichen Scopes zustimmen, die Graph Explorer in unserem Namen nutzen darf, etwa "Directory.Read.All", "User.Invite.All" oder "GroupMember.Read.All" [2]. Nur wenn die Berechtigung erteilt und der Nutzung für diese zugestimmt wurde, darf die Anwendung auch Gebrauch davon machen. Denn die zugestimmten Scopes landen im "access_token", das das AAD der Anwendung ausstellt. Fehlen Scopes, kann die Graph-API die Anfrage verweigern und Graph Explorer samt angemeldetem Benutzer an der Ausführung hindern.
Um Graph Explorer zusätzliche Berechtigungen zu erteilen, melden Sie sich im AAD-Portal als "Application Administrator" oder "Global Administrator" an, wechseln zu "Enterprise Applications" und wählen "Graph Explorer" aus. Unter "Permissions" sehen Sie die Übersicht aller Berechtigungen, die Graph Explorer bereits für Benutzer in Ihrem Tenant hat. Um die Berechtigungen anzupassen, laden Sie via "Review Permissions" und "This Application has more Permissions than I want" ein Skript für das Azure-AD-Modul herunter, das die Berechtigungen löscht und Sie anschließend von Neuem beginnen lässt. Für einfache Tests nutzen Sie den Knopf "Grant admin consent for Contoso", womit Graph Explorer alle Berechtigungen erhält, die es für ausreichendes Testen benötigt. Dies sind aber immer nur so viele Berechtigungen, wie der angemeldete Benutzer selbst hat. Ein normaler Benutzer kann mit Graph Explorer nicht die Mailboxen anderer Benutzer löschen, selbst wenn Graph Explorer die Berechtigung dazu hat.
Endpunkte verstehen
Die Anfrage-URL, mit der Sie Graph signalisieren, für welches Objekt Sie sich interessieren, ist hierarchisch aufgebaut. Der Aufbau gibt eine Struktur vor, in der klar ist, welchen Graphen Sie meinen, welche Version Sie davon nutzen möchten sowie welchen Objekttyp und welche Attribute davon Sie ansprechen wollen. Kurz gesagt: Sie definieren den Endpunkt. Wenn Sie sich nach
erkundigen, erhalten Sie ohne Umwege die Jobbeschreibung des angefragten Benutzers aus "users". Die Endpunkte können auch mehrere Ebenen umfassen, etwa
Bild 2: Wollen Anwendungen auf APIs oder Ressourcen zugreifen, muss ein Administrator vorher zustimmen.
Ergebnisse filtern
Alle Ergebnisse für eine Anfrage zurückzuerhalten, ist zwar für eine Überprüfung der Anfragelogik und zum Auskundschaften der Graph-Calls interessant. Sie brauchen aber in den seltensten Fällen immer alle Objekte und alle Attribute. Sie benötigen also – wie in anderen Abfragesprachen wie LDAP oder SQL auch – eine Möglichkeit zu suchen, filtern, zählen und sortieren.
Da die Requests für Graph über HTTPS laufen, werden Filter und Suchparameter in die HTTP-Anfrage verpackt. Interessieren Sie sich für die Gruppen im Tenant, die einen bestimmten Präfix besitzen, fragen Sie nach: "https://graph.microsoft. com/v1.0/groups?$filter=startsWith(displayName,'Windows')". Dies zeigt alle Gruppen an, die "Windows" als Präfix im "DisplayName" tragen. Sie sagen Graph mit dem Schlagwort "$filter", angeführt vom Dollarzeichen, dass nun die Filterlogik folgt. "StartsWith" ist eine der Methoden, die Sie für die Suche verwenden können, neben anderen wie "eq" für "equals", "le" für "less or equal", "ge" für "greater or equal" oder "endsWith()".
Um die Objekte auf eine Liste benötigter Attribute zu kürzen, teilen Sie Graph mit, welche Attribute relevant sind. Dazu nehmen Sie die letzte Anfrage und fügen "&$select=displayName,onPremisesSync-Enabled" an. Mit dem Kaufmanns-Und und dem Stichwort "$select" geben Sie die Liste der interessanten Attribute an. Über "OnPremisesSyncEnabled" für Gruppen bringen Sie in Erfahrung, ob die Gruppe vom AD synchronisiert wird oder nativ im AAD existiert. Die jeweiligen Suchkommandos signalisieren Sie mit dem Dollarzeichen ("$") . Nutzen Sie mehrere der Suchkommandos in einer Anfrage, trennen Sie die Kommandos mit dem "&".
Sie können auch dediziert nach Mitgliedern einer Gruppe fragen, indem Sie die Gruppe mit ihrer ObjectID referenzieren und nach "members" fragen:
Als Rückgabe im Graph Explorer sehen Sie dann mehrere Objekte, die jeweils einen Benutzer darstellen. Andere Attribute der Gruppe liefert die Anfrage nicht mit.
Sind Sie nur an M365-Gruppen interessiert, die in der Cloud erstellt und verwaltet werden, sollten Sie die Anfrage so formulieren:
Der Filter mit "groupTypes/any()" beschreibt eine Suche in mehrwertigen Feldern, denn das Feld "GroupTypes" kann mehrere Werte besitzen. Sind Sie nur an den Teams in Ihrem Tenant interessiert, sollte der Filter nach "resourceProvisioningOptions" suchen:
Darin wird gekennzeichnet, in welchen Diensten die Gruppe provisioniert wird.
Wenn Sie Ergebnisse zusätzlich zur Ausgabe zählen lassen wollen, fügen Sie "$count=true" in die Anfrage ein. Sie müssen dazu allerdings einen Request-Header einbauen. Hierzu klicken Sie auf "Request Headers" im oberen Anfrageteil des Graph Explorers und fügen "ConsistencyLevel" als "Key" und "eventual" als "Value" ein und bestätigen mit dem Knopf "Add". Starten Sie jetzt die Suchanfragen für M365-Gruppen und für Teams noch einmal, sehen Sie, dass die Antwort eine weitere Zeile einfügt, die die Ergebnisanzahl beschreibt: "@odata.count: 16". Das funktioniert auch für das Zählen von Gruppenmitgliedern:
Benutzer eines bestimmten Kriteriums können Sie ebenfalls zählen lassen. Mit dem folgenden Befehl zählt Graph die Anzahl der externen Identitäten (Benutzertyp "Gast"):
Objekte schreiben Sie mit Graph über die POST- und PATCH-Kommandos. Neue Objekte erstellen Sie per POST, während Sie ein oder mehrere Attribute bestehender Objekte mit PATCH ändern. Modifizieren Sie mehrere Objekte, müssen Sie die geänderten oder neuen Attribute des Zielobjektes definieren und mit der Anfrage abschicken. Das erledigen Sie mit Hilfe des "Request Body". Dieser wird ebenfalls im JSON-Format beschrieben. Neue Objekte können Sie, sofern Sie die notwendigen Berechtigungen haben, immer im Verzeichnis anlegen. Bestehende Objekte sind natürlich nur dann beschreibbar, wenn sie auch in der Cloud verwaltet werden: Objekte, die mit Azure AD Connect vom Windows-AD synchronisiert werden, lassen sich in der Cloud nur bedingt modifizieren.
Einen neuen Benutzer erstellen Sie, indem Sie die Anfragemethode von "Get" nach "Post" ändern und die URL anpassen zu: "https://graph.microsoft.com/v1.0/users". Im "Request Body" fügen Sie alle Attributwerte ein, die Sie für die Erzeugung benötigen, hier am Beispiel des Users "Madeline Reuters":
Als Ergebnissatz im Resultatfeld sehen Sie die ObjektID ("id") sowie weitere Attribute, die mit zum Benutzerobjekt gehören. Der HTTP-Antwortcode ist 201.
Um den Benutzeraccount zu ändern, passen Sie diesen mit der Patch-Methode mit einzelnen Attributen an:
Im Aufruf können Sie den Anmeldenamen des Benutzers oder die ObjektID nennen:
{
"displayName": "Madeline Reuters (disabled)",
"accountEnabled": false
}
Der Anzeigename ändert sich daraufhin und der Account wird gesperrt – den Antwortcode "204" finden Sie im unteren Teil des Graph Explorers. Die Return Codes sowie die Meldungen, die Sie im Fall eines Problems vom Graph Explorer sehen, gibt Microsoft Graph direkt aus. Wenn Sie weitere Automatisierung wie Skripte oder Anwendungen planen, lohnt es sich, die Negativfälle ebenfalls zu testen und für die Fehlerbehandlung genauer zu unterscheiden.
Das Erstellen einer Gruppe erledigen Sie ebenfalls über einen POST-Request, diesmal an den Endpunkt "Groups" gerichtet. Sie können auch schon die Gruppenmitgliedschaft und den Besitzer als Referenzen via Objekt-IDs angeben:
{
"description": "Projektarbeit Werkstudenten Sommer 2021","displayName": "Werkstudenten Sommer 2021","groupTypes": [
Der Besitzer und die Mitglieder erscheinen als Graph-Objekte. Beim Erstellen des Objektes können Sie bis zu 20 Mitglieder oder Besitzer direkt mit anlegen – alle weiteren Besitzer oder Mitglieder müssen Sie dann in PATCH-Operationen nach der Objektanlage nachreichen.
Fazit
Um für die Microsoft-Cloud Skripte oder Anwendungen zu schreiben, führt kein Weg an der PowerShell und Microsoft Graph vorbei. Für komplexe Anfragen oder viele Requests an unterschiedliche Endpunkte sowie für die Feinabstimmung bei Anfragen mit vielen Ergebnissen hilft der Graph Explorer, Ergebnisse schnell zu validieren und die Anfragen zu schärfen. Zudem unterstützt Graph Explorer auch dabei, die richtigen Berechtigungen für die Graph-Abfragen zu finden und für das Skript oder die Anwendung durch einen Administrator freizuschalten. Im zweiten Teil des Workshops erstellen wir eine neue Anwendung im Azure AD, weisen ihr Graph-Berechtigungen zu und nutzen das erstellte Service Principal, um Anfragen an Graph automatisiert auszuführen.