· Simon Hartl · Systemintegration  · 15 min read

Apache Camel & Microsoft Entra ID: Gruppenmitglieder auslesen – eine professionelle Lösung

Lerne, wie du mit Apache Camel und der Microsoft Graph API Gruppenmitglieder aus Microsoft Entra ID (ehemals Azure AD) – inkl. verschachtelter Mitgliedschaften – effizient ausliest. Unsere praxiserprobte Lösung kombiniert OAuth2-Authentifizierung, YAML-Routen und CSV-Export für eine professionelle Systemintegration mit Apache Camel und Microsoft Entra ID.

Lerne, wie du mit Apache Camel und der Microsoft Graph API Gruppenmitglieder aus Microsoft Entra ID (ehemals Azure AD) – inkl. verschachtelter Mitgliedschaften – effizient ausliest. Unsere praxiserprobte Lösung kombiniert OAuth2-Authentifizierung, YAML-Routen und CSV-Export für eine professionelle Systemintegration mit Apache Camel und Microsoft Entra ID.

Praktische Systemintegration: Apache Camel und Microsoft Entra ID

English version is available

Einleitung: Komplexe Szenarien mit Apache Camel meistern

Apache Camel ist ein flexibles Open-Source-Integrationsframework für die Java-Plattform, das den Datenaustausch zwischen Systemen vereinfacht – von einfachen Dateioperationen bis zu komplexen API-Integrationen. Viele Tutorials zeigen nur grundlegende Beispiele wie das Einlesen von Dateien oder einfache Datenverarbeitungen. Das ist ideal für den Einstieg, reicht in der Praxis aber oft nicht aus.

In diesem Artikel gehen wir einen Schritt weiter: Wir bauen eine produktionsreife Camel-Integration, die Mitglieder einer Microsoft Entra ID-Gruppe (ehemals Azure Active Directory) ausliest – inklusive verschachtelter Mitgliedschaften – und in einer CSV-Datei speichert. Dabei kombinieren wir Camel-Routen mit etwas Programmcode, um API-Authentifizierung, Datenfilterung und Dateiausgabe elegant umzusetzen.

Integration von Microsoft Entra ID über Graph API mit Apache Camel zur Ausgabe einer CSV-Datei

Am Ende des Artikels wirst du nicht nur ein besseres Verständnis für Apache Camel haben, sondern auch wissen, wie du anspruchsvolle Integrationen mit Microsoft Entra ID selbst umsetzen kannst.

Für wen ist dieser Artikel?

Dieser Artikel richtet sich an Entwickler und IT-Profis, die bereits Grundkenntnisse in Java oder einer ähnlichen Programmiersprache haben und ihre Fähigkeiten in der Systemintegration ausbauen möchten.

Wir behandeln nicht nur die Grundlagen von Camel, sondern auch fortgeschrittene Techniken wie OAuth-Authentifizierung, API-Handling und die Integration von benutzerdefiniertem Code. Du kannst jeden Schritt anhand von Codebeispielen und Konfigurationsdateien nachvollziehen und direkt in eigenen Projekten einsetzen.

Vorbereitung

Apache Camel installieren

Apache Camel ist ein leistungsstarkes Open-Source-Integrationsframework für die Java-Plattform. Für unser Beispiel nutzen wir Camel 4.10 (LTS) mit Java 21+.

Java installieren

JBang installieren

  • Anleitung: Camel JBang Installation
  • JBang ermöglicht es, Camel-Routen ohne komplexe Build-Konfiguration auszuführen.

Camel-CLI einrichten

  • Mit JBang den Camel-Befehl installieren:
jbang app install camel@apache/camel

Dieser Befehl lädt die benötigten Komponenten herunter und macht den camel Befehl verfügbar.

Ergebnis

Du kannst jetzt Camel-Routen und Java-Code direkt ausführen, ohne Maven- oder Gradle-Projektstruktur anlegen zu müssen.

Microsoft Entra vorbereiten

Damit Camel auf Microsoft Entra ID (ehemals Azure Active Directory) zugreifen kann, musst du eine Anwendung registrieren und Berechtigungen vergeben.

1. Anmelden

Melde dich im Microsoft Entra Admin Center an.

2. App registrieren

Navigiere zu Microsoft Entra ID → App-Registrierungen.

Entra Side Menu

Neue Registrierung auswählen.

Entra App-Registrierung

  • Name: CamelDemo
  • Kontotyp: Nur Organisationsverzeichnis
  • Registrieren klicken.

Entra Anwendung registrieren

3. IDs notieren

Nach der Registrierung findest du auf der Übersichtsseite:

  • Anwendungs-ID (Client ID)
  • Verzeichnis-ID (Tenant ID)

Anwendungsinformation inkl. Client ID

4. Geheimen Clientschlüssel erstellen

  • Menü: Zertifikate & GeheimnisseNeuer geheimer Clientschlüssel.

Clientschlüssel anlegen

  • Name eingeben und Hinzufügen wählen.

Clientschlüssel Details

⚠️ Wichtig: Schlüssel wird nur einmal angezeigt – sofort kopieren und sicher aufbewahren.

Clientschlüssel Secret

5. Berechtigungen vergeben

  • Menü: API-BerechtigungenBerechtigung hinzufügen.

API-Berechtigung

  • API: Microsoft GraphAnwendungsberechtigungen.
  • Directory.Read.All auswählen.
  • Berechtigung hinzufügen wählen.

Berechtigung hinzufügen

  • Administratorenzustimmung erteilen. Administratorenzustimmung

💡 Sicherheitstipp: Hinterlege client_secret niemals direkt in einem öffentlichen Repository. Nutze Umgebungsvariablen oder einen Secret-Manager.

Mit dieser Vorbereitung sind Camel und Microsoft Entra so eingerichtet, dass wir direkt mit der Routenerstellung beginnen können.

Entwicklung der Route

Jetzt, da unsere Umgebung vorbereitet ist, können wir uns der eigentlichen Entwicklung der Camel-Route widmen. Unser Ziel ist es, eine produktionsreife Lösung zu erstellen, die nicht nur funktioniert, sondern auch Aspekte wie Logging, Effizienz und Wiederverwendbarkeit berücksichtigt. Um dies zu erreichen, wird die Route modular in mehreren Teilen aufgebaut:

Apache Camel Crashkurs - Message-basierte Integration einfach erklärt

Apache Camel ist ein flexibles Open-Source-Integrationsframework für Java, das den Datenaustausch zwischen Systemen vereinfacht – von einfachen Dateioperationen bis zu komplexen API-Integrationen (z. B. mit Microsoft Entra ID oder REST-Services).

Kernkonzepte von Camel

KomponenteBeschreibungBeispiel
MessageGrundlegende Einheit der Datenübertragung. Enthält alle Informationen für die Verarbeitung.Eine HTTP-Anfrage oder eine Datei.
HeaderMetadaten wie Routing-Informationen, Auth-Tokens oder Kontextdaten.Authorization Header zur Authentifizierung in HTTP Requests, CamelHttpPath als URL Pfad bei einer HTTP Requests
BodyDie Nutzdaten (z. B. JSON, XML, CSV), die zwischen Systemen ausgetauscht werden.{"user": "max.mustermann", "group": "Developers"}

Wie Camel funktioniert

  1. Komponenten empfangen, transformieren und leiten Nachrichten weiter (z. B. HTTP, File, Azure).

  2. Routen definieren den Datenfluss – z. B.:

  • Eine Datei einlesen → Daten transformieren → an eine API senden.
  • Eine API-Abfrage (z. B. Microsoft Graph) → Antwort filtern → als CSV speichern.
  1. Vorteile:
  • Flexibel: Über 300 vorgefertigte Komponenten (z. B. für OAuth2, JMS, Kafka).
  • Erweiterbar: Eigene Logik lässt sich mit Java, Groovy oder Script-Sprachen einbinden.
  • Einfach: Routen können in Java, XML oder YAML definiert werden (wie in diesem Tutorial).

Warum Camel?

Durch sein message-basiertes Design lässt sich Camel leicht an unterschiedliche Anforderungen anpassen – ideal für Systemintegration, ETL-Prozesse oder Microservices.

Konzept der Routen

Jetzt zum Konzept unserer Lösung, die aus mehreren Routen besteht.

  1. Authentifizierungs-Teil: Dieser Teil der Routen ist für das OAuth-Login und das Handling der Tokens zuständig. Eine sichere und effiziente Authentifizierung ist entscheidend, um Zugriff auf die Microsoft Entra ID-Daten zu erhalten.

  2. Worker-Teil: Dieser Teil der Routen ist für das Auslesen der Gruppen und das Abfragen der Gruppenmitglieder verantwortlich. Hier wird die eigentliche Arbeit erledigt, nachdem die Authentifizierung erfolgreich abgeschlossen wurde.

Durch diese modulare Aufteilung können wir sicherstellen, dass jeder Teil der Routen klar definiert und wiederverwendbar ist. Dies erleichtert nicht nur die Wartung, sondern auch das Testen und Debuggen der Anwendung.

Konfigurationsdateien

Um unsere Lösung konfigurierbar und flexibel zu gestalten, speichern wir die notwendigen Parameter in einer Konfigurationsdatei namens application.properties. Diese Datei ermöglicht es uns, die Anwendung einfach an verschiedene Umgebungen anzupassen, ohne den Code ändern zu müssen.

# Authentication URI
ms.login.uri = https://login.microsoftonline.com/{{ms.graph.tenant_id}}/oauth2/v2.0/token

# Number of seconds a new token is requested before it expires
token_grace_period = 60

# Name of the group to fetch
ad_group.display_name = TestGroup

# Application configuration
ms.graph.tenant_id = REPLACE_WITH_YOUR_TENANT_ID
ms.graph.client_id = REPLACE_WITH_YOUR_CLIENT_ID
ms.graph.client_secret = REPLACE_WITH_YOUR_CLIENT_SECRET

In dieser Datei musst du folgende Änderungen vornehmen:

  • ms.graph.tenant_id: Ersetze diesen Platzhalter mit deiner Mandanten-ID. Diese findest du in der Übersichtsseite deiner App-Registrierung im Feld “Verzeichnis-ID (Mandant)” (siehe Screenshot zu Schritt 4).

  • ms.graph.client_id: Ersetze diesen Platzhalter mit deiner Anwendungs-ID. Diese findest du ebenfalls in der Übersichtsseite deiner App-Registrierung im Feld “Anwendungs-ID (Client)” (siehe Screenshot zu Schritt 4).

  • ms.graph.client_secret: Ersetze diesen Platzhalter mit dem geheimen Clientschlüssel, den du in Schritt 6 erstellt und kopiert hast.

  • ad_group.display_name: Hier trägst du den Namen der Gruppe ein, deren Mitglieder du auslesen möchtest.

⚠️ ACHTUNG: Bei Verwendung eines Source-Code-Repositories wie Git solltest du sicherstellen, dass solche Secrets niemals in dein Repository committed werden. Verwende stattdessen Umgebungsvariablen oder sichere Geheimnisverwaltungssysteme, um sensible Informationen zu speichern und zu verwalten.

Entwicklung der Authentifizierungsroute

Die Authentifizierung ist ein zentraler Bestandteil unserer Anwendung, und wir steuern die notwendigen Parameter bequem über die application.properties. In diesem Abschnitt erstellen wir eine Route, die sich um die Anmeldung und das Abrufen des Auth-Tokens kümmert. Der Code dazu wird in der Datei auth-handler.camel.yaml definiert.

Konzept der Route

Der Auth-Handler ist dafür verantwortlich, einen Auth-Token bereitzustellen. Um die Effizienz zu steigern, wird der Token gecached, sodass nicht bei jedem Aufruf eine neue Anmeldung durchgeführt werden muss. Ist bereits ein Token vorhanden, wird überprüft, ob dieser noch gültig ist. Dabei wird eine konfigurierbare Anzahl von Sekunden vor dem eigentlichen Ablauf eine neue Anmeldung durchgeführt, was durch den Parameter token_grace_period in der Konfiguration gesteuert wird.

Sollte kein gültiger Token vorhanden sein, wird automatisch eine neue Anmeldung durchgeführt. Der neue Token wird dann im Cache gespeichert und dem Aufrufer zur Verfügung gestellt. Ein besonderes Highlight dieser Route ist die einfache Integration von Groovy-Code, der die Logik klar und wartbar gestaltet. Dies zeigt eine der großen Stärken von Camel: die einfache Integration von benutzerdefiniertem Code, um spezifische Anforderungen zu erfüllen, die über Standardfunktionen hinausgehen.

In vielen anderen Integrationslösungen wäre die Implementierung einer solchen Logik mit erheblichen Aufwand verbunden. Oftmals müsste man auf externe Skripte oder zusätzliche Middleware zurückgreifen, was die Komplexität erhöht und die Wartbarkeit erschwert. Camel hingegen ermöglicht es, solche Logiken direkt in die Routen einzubetten, was die Entwicklung vereinfacht und die Performance optimiert.

Zusätzlich haben wir erweiterten Logging-Code eingebaut, um sicherzustellen, dass Fehler schnell identifiziert und behoben werden können.

Implementierung der Route

Der Code der Route kann unter auth-handler.camel.yaml geladen werden.

Was dieser Abschnitt macht: Die folgende Route route-get-token prüft, ob ein gültiger OAuth-Token im Cache liegt. Falls nicht, wird ein neuer Token von Microsoft Entra ID angefordert und gespeichert.

- route:
    id: route-get-token
    from:
      uri: direct
      parameters:
        name: getToken
      steps:
        - script:
            expression:
              groovy:
                expression: |
                  long now = (long)System.currentTimeMillis()/1000
                  long expiresAt = exchange.getVariable("route:expiresAt") ?: 0

                  long gracePeriod = {{token_grace_period}}
                  boolean expired = (now + gracePeriod) >= expiresAt

                  exchange.setProperty('now', now)
                  exchange.setProperty('expiresAt', expiresAt)
                  exchange.setProperty('expiresIn', expiresAt-now)
                  exchange.setProperty('gracePeriod', gracePeriod)
                  exchange.setProperty('expired', expired)
        - log:
            loggingLevel: INFO
            message: "Checking token expiration: now: ${exchangeProperty.now}, expiresAt:
              ${exchangeProperty.expiresAt}, gracePeriod:
              ${exchangeProperty.gracePeriod}, expired:
              ${exchangeProperty.expired}"
        - choice:
            otherwise:
              description: use existing token
              steps:
                - log:
                    message: Using cached token (expires in ${exchangeProperty.expiresIn} seconds).
            when:
              - description: retrieve a new token
                steps:
                  - log:
                      loggingLevel: INFO
                      message: Token is expired or about to expire. Fetching a new one.
                  - to:
                      uri: direct
                      parameters:
                        name: fetchToken
                  - script:
                      expression:
                        groovy:
                          expression: |
                            long expiresAt = (System.currentTimeMillis()/1000) + body.expires_in
                            
                            exchange.setProperty('expiresAt', expiresAt)
                            exchange.setProperty('expiresIn', body.expires_in)

                            exchange.setVariable('route:expiresAt', expiresAt)
                            exchange.setVariable('route:token', body.access_token)
                            
                            exchange.in.body = null
                  - log:
                      message: New token obtained successfully (expires in ${exchangeProperty.expiresIn} seconds).
                expression:
                  groovy:
                    expression: exchangeProperty.expired
        - removeHeaders:
            pattern: "*"
        - setHeader:
            expression:
              groovy:
                expression: "\"Bearer ${exchange.getVariable('route:token')}\""
            name: Authorization

Zusammenfassung:

  • Prüft Ablaufzeit (expiresAt) gegen aktuellen Zeitpunkt.
  • Ruft bei Bedarf fetchToken auf.
  • Speichert neuen Token in Variablen (route:token) für spätere API-Aufrufe.

Die zweite Route in der gleichen Datei ist für das eigentliche Abrufen des Tokens zuständig.

Was dieser Abschnitt macht: Die folgende Route route-fetch-token holt einen neuen Access Token von Microsoft Entra ID über den Client-Credentials-Flow und speichert ihn als JSON-Objekt im Exchange.

- route:
    id: route-fetch-token
    from:
      uri: direct
      parameters:
        name: fetchToken
      steps:
        - setBody:
            expression:
              simple:
                expression: client_id={{ms.graph.client_id}}&scope=https://graph.microsoft.com/.default&client_secret={{ms.graph.client_secret}}&grant_type=client_credentials
        - to:
            uri: https
            parameters:
              httpMethod: POST
              httpUri: "{{ms.login.uri}}"
        - unmarshal:
            json: {}

Zusammenfassung:

  • Baut HTTP-POST-Anfrage mit client_id, client_secret und Scope.
  • Sendet Anfrage an ms.login.uri.
  • Antwort wird als JSON geparst und im Exchange-Body bereitgestellt.

Der Code zeigt, wie einfach es ist, komplexe Logik in Camel zu integrieren und wie flexibel das Framework bei der Implementierung von Integrationslösungen ist.

Route zum Auslesen der Gruppenmitglieder

Nachdem wir erfolgreich einen Auth-Token abgerufen haben, können wir uns nun der eigentlichen Aufgabe widmen: dem Auslesen der Mitglieder einer bestimmten Gruppe in Microsoft Entra ID. Diese Route wird in einer YAML-Datei definiert und nutzt den zuvor abgerufenen Token, um auf die Microsoft Graph API zuzugreifen und die Gruppenmitglieder zu extrahieren.

Konzept der Route

In diesem Demo wird ein Timer mit einem einmaligen Aufruf (repeatCount: 1) verwendet, um den Prozess zu starten. Im Produktivbetrieb könnte dieser Timer so konfiguriert werden, dass er beispielsweise einmal pro Tag ausgelöst wird, um regelmäßig aktualisierte Daten zu erhalten.

Zuerst wird der Auth-Token abgerufen, wie in der Authentifizierungsroute beschrieben. Dieser Token ist notwendig, um sich bei der Microsoft Graph API zu authentifizieren und autorisierten Zugriff auf die Gruppendaten zu erhalten.

Anschließend wird eine HTTP-Anfrage an die Microsoft Graph API gesendet, um die Gruppe anhand ihres Anzeigenamens zu suchen. Sobald die Gruppen-ID ermittelt wurde, wird eine weitere Anfrage gesendet, um alle Mitglieder dieser Gruppe, einschließlich geschachtelter Mitglieder, abzurufen.

Ein besonderes Merkmal dieser Route ist die Filterung der Ergebnisse, um nur Benutzer zu berücksichtigen. Dies wird durch einen Groovy-Skriptblock erreicht, der die Antwort der API filtert und nur Einträge mit dem Typ “User” zurückgibt. Für die Gruppenmitglieder werden die id, der displayName und der userPrincipalName in eine CSV-Datei geschrieben. Diese Datei wird mit dem Namen group-members.csv gespeichert und enthält alle relevanten Benutzerinformationen.

Implementierung der Route

Die YAML-Datei zur Route kann hier gefunden werden: list-group-members.camel.yaml.

Was dieser Abschnitt macht: Diese Route startet einmalig durch einen Timer, holt den Auth-Token, ermittelt die Gruppen-ID anhand des Namens und ruft alle Mitglieder ab. Nur Benutzer werden herausgefiltert und in group-members.csv gespeichert.

- route:
    id: route-4231
    from:
      uri: timer
      parameters:
        period: "1000"
        repeatCount: "1"
        timerName: timer
      steps:
        - to:
            uri: direct
            parameters:
              name: getToken
              timeout: "5000"
        - to:
            uri: https
            parameters:
              httpMethod: GET
              httpUri: https://graph.microsoft.com/v1.0/groups?$filter=displayName eq
                '{{ad_group.display_name}}'&$select=id,displayName
        - unmarshal:
            json:
              prettyPrint: false
        - setProperty:
            expression:
              simple:
                expression: ${body[value][0][id]}
            name: group-id
        - removeHeaders:
            excludePattern: Authorization
            pattern: "*"
        - setHeaders:
            headers:
              - expression:
                  simple:
                    expression: /v1.0/groups/${exchangeProperty.group-id}/transitiveMembers
                name: CamelHttpPath
              - expression:
                  constant:
                    expression: $select=id,userPrincipalName,displayName
                name: CamelRestHttpQuery
        - to:
            uri: https
            parameters:
              httpMethod: GET
              httpUri: https://graph.microsoft.com
        - unmarshal:
            json: {}
        - setBody:
            expression:
              simple:
                expression: ${body[value]}
        - setBody:
            description: Filter for users only
            expression:
              groovy:
                expression: |-
                  body.findAll { entry ->
                    entry.'@odata.type' == '#microsoft.graph.user'
                  }
        - marshal:
            csv:
              header:
                - id
                - displayName
                - userPrincipalName
              headerDisabled: false
        - to:
            uri: file
            parameters:
              directoryName: "."
              fileName: group-members.csv
        - log:
            message: Group members of {{ad_group.display_name}} written to
              ${header.CamelFileNameProduced}

Zusammenfassung:

  • Timer wird einmal repeatCount=1 eingerufen und damit die Route getriggert.
  • Holt Auth-Token (getToken).
  • Ermittelt Gruppen-ID anhand displayName.
  • Ruft /transitiveMembers auf, um auch verschachtelte Mitgliedschaften zu erfassen.
  • Filtert nur Benutzer (#microsoft.graph.user).
  • Exportiert Ergebnis in group-members.csv.

Diese Route zeigt, wie einfach es ist, mit Apache Camel komplexe Integrationsaufgaben zu lösen und Daten aus verschiedenen Quellen zu verarbeiten und zu speichern. Durch die Verwendung von Groovy-Skripten und die flexible Konfiguration von Routen können wir präzise steuern, wie Daten verarbeitet werden, und gleichzeitig die Lesbarkeit und Wartbarkeit des Codes sicherstellen.

Grafische Tools zur Darstellung und Bearbeitung von Routen

Für Einsteiger wie auch erfahrene Entwickler kann der Einsatz grafischer Tools die Arbeit mit Apache Camel deutlich vereinfachen. Sie bieten eine visuelle Darstellung der Routen und ermöglichen es, Integrationsszenarien intuitiv zu erstellen, anzupassen und zu debuggen.

Besonders nützlich sind hier Plugins für VS Code, wie Kaoto und Camel Karavan. Diese Plugins bieten eine grafische Benutzeroberfläche, die es ermöglicht, Camel-Routen per Drag-and-Drop zu erstellen und zu bearbeiten. Dies erleichtert das Verständnis und die Wartung der Routen, insbesondere für diejenigen, die neu in der Entwicklung von Integrationslösungen mit Camel sind.

Screenshot der Auth-Handler Route

Vorteile grafischer Tools

  • Einfacher Einstieg: Grafische Tools bieten eine intuitive Benutzeroberfläche, die den Einstieg in die Entwicklung von Camel-Routen erleichtert.
  • Visuelle Darstellung: Die visuelle Darstellung der Routen hilft dabei, komplexe Integrationsszenarien besser zu verstehen und zu debuggen.
  • Effiziente Bearbeitung: Durch Drag-and-Drop und andere grafische Bearbeitungsfunktionen können Routen schneller und effizienter erstellt und angepasst werden.

Diese Tools sind besonders nützlich für Einsteiger, die sich mit Apache Camel vertraut machen möchten, aber auch erfahrene Entwickler können von den visuellen Darstellungen und Bearbeitungsmöglichkeiten profitieren.

Aufruf der Route

Nachdem wir die Routen für die Authentifizierung und das Auslesen der Gruppenmitglieder definiert haben, ist es an der Zeit, diese in Aktion zu sehen. Der Aufruf der Route erfolgt über die Kommandozeile mit dem folgenden Befehl:

camel run application.properties auth-handler.camel.yaml list-group-members.camel.yaml

Beim Ausführen des obigen Befehls siehst du eine Ausgabe ähnlich der folgenden:

Running integration with the following configuration:
    --camel-version=4.10.6
2025-08-07 16:16:23.726 INFO 30040 --- [ main] org.apache.camel.main.MainSupport : Apache Camel (JBang) 4.10.6 is starting
2025-08-07 16:16:23.879 INFO 30040 --- [ main] org.apache.camel.main.MainSupport : Running Mac OS X 15.5 (aarch64)
2025-08-07 16:16:23.879 INFO 30040 --- [ main] org.apache.camel.main.MainSupport : Using Java 23.0.2 (OpenJDK 64-Bit Server VM) with PID 30040
2025-08-07 16:16:23.928 INFO 30040 --- [ main] org.apache.camel.main.BaseMainSupport : Properties location: file:application.properties
2025-08-07 16:16:24.373 INFO 30040 --- [ main] he.camel.cli.connector.LocalCliConnector : Camel JBang CLI enabled
2025-08-07 16:16:24.848 INFO 30040 --- [ main] .main.download.MavenDependencyDownloader : Downloaded: org.apache.camel:camel-csv:4.10.6 (took: 303ms) from: central@https://repo1.maven.org/maven2
2025-08-07 16:16:24.867 INFO 30040 --- [ main] e.camel.impl.engine.AbstractCamelContext : Apache Camel 4.10.6 (auth-handler) is starting
2025-08-07 16:16:25.055 INFO 30040 --- [ main] e.camel.impl.engine.AbstractCamelContext : Routes startup (total:3)
2025-08-07 16:16:25.055 INFO 30040 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route-get-token (direct://getToken)
2025-08-07 16:16:25.055 INFO 30040 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route-fetch-token (direct://fetchToken)
2025-08-07 16:16:25.055 INFO 30040 --- [ main] e.camel.impl.engine.AbstractCamelContext : Started route-4231 (timer://timer)
2025-08-07 16:16:26.447 INFO 30040 --- [-timer://timer] auth-handler.camel.yaml:23 : Checking token expiration: now: 1754576186, expiresAt: 0, gracePeriod: 60, expired: true
2025-08-07 16:16:26.455 INFO 30040 --- [-timer://timer] auth-handler.camel.yaml:38 : Token is expired or about to expire. Fetching a new one.
2025-08-07 16:16:26.790 INFO 30040 --- [-timer://timer] auth-handler.camel.yaml:64 : New token obtained successfully (expires in 3599 seconds).
2025-08-07 16:16:27.270 INFO 30040 --- [-timer://timer] list-group-members.camel.yaml:73 : Group members of TestGroup written to ./group-members.csv

Wenn du deine Routen während der Entwicklung schnell anpassen und testen möchtest, kannst du zusätzlich den Entwicklermodus aktivieren. Dazu fügst du einfach die Option --dev hinzu:

camel run --dev application.properties auth-handler.camel.yaml list-group-members.camel.yaml

Im Entwicklermodus überwacht Camel die angegebenen Dateien und startet die Integration automatisch neu, sobald du eine Änderung speicherst. Dadurch entfällt das manuelle Stoppen und erneute Starten der Anwendung – ideal, um Konfigurationsanpassungen, Routenänderungen oder neue Code-Snippets sofort auszuprobieren.

Was passiert beim Aufruf?

  1. Start der Anwendung: Mit dem Befehl camel run wird die Camel-Anwendung gestartet. Dabei werden die Konfigurationsdatei application.properties sowie die beiden YAML-Dateien auth-handler.camel.yaml und list-group-members.camel.yaml geladen.

  2. Authentifizierung: Zuerst wird die Route zur Authentifizierung ausgeführt, um einen Auth-Token von Microsoft Entra ID abzurufen.

  3. Auslesen der Gruppenmitglieder: Sobald der Auth-Token erfolgreich abgerufen wurde, wird die Route zum Auslesen der Gruppenmitglieder gestartet, die Anfragen an die Microsoft Graph API sendet.

  4. Speichern der Ergebnisse: Die gefilterten Daten werden in eine CSV-Datei geschrieben. Nach erfolgreichem Abschluss des Prozesses findest du die Gruppenmitglieder in der Datei group-members.csv im Arbeitsverzeichnis.

Die Camel-Anwendung läuft nach abarbeiten der Route bzw. des Timer-Events weiter, um weitere Anfragen oder Aufgaben zu bearbeiten. Du kannst die Anwendung jederzeit durch Drücken von Ctrl-C im Terminal beenden.

Ergebnis

Nach dem erfolgreichen Aufruf der Route und der Ausführung der definierten Schritte findest du die Datei group-members.csv in deinem Arbeitsverzeichnis. Diese Datei enthält eine Liste aller Gruppenmitglieder mit den folgenden Informationen:

  • id: Die eindeutige ID des Benutzers.
  • displayName: Der Anzeigename des Benutzers.
  • userPrincipalName: Der Benutzername des Benutzers.

Mit diesen einfachen Befehlen und den definierten Routen kannst du sicherstellen, dass die richtige Version von Camel verwendet wird und die Mitglieder einer Microsoft Entra ID-Gruppe ausgelesen und in einer CSV-Datei gespeichert werden. Dies zeigt, wie einfach und effizient komplexe Integrationsaufgaben mit Apache Camel gelöst werden können.

Fazit: Apache Camel für professionelle Microsoft Entra ID-Integrationen

In diesem Artikel haben wir gezeigt, wie du mit Apache Camel eine robuste und effiziente Lösung zur Integration mit Microsoft Entra ID (ehemals Azure AD) entwickelst. Durch die Kombination von Camel-Routen, benutzerdefiniertem Groovy-Code und der Microsoft Graph API konnten wir eine Anwendung erstellen, die Gruppenmitglieder inkl. verschachtelter Mitgliedschaften ausliest und in einer CSV-Datei speichert.

Dabei haben wir nicht nur die Grundlagen von Apache Camel behandelt, sondern auch fortgeschrittene Techniken wie:

  • OAuth2-Authentifizierung mit Client Credentials Flow und Token-Caching,
  • Modulare YAML-Routen für Wartbarkeit und Skalierbarkeit,
  • Datenfilterung und CSV-Export mit Camel’s Marshaling-Komponenten.

Apache Camel erweist sich damit als leistungsfähiges Integrationsframework für Enterprise-Szenarien – ob für Systemintegration, Automatisierung oder ETL-Prozesse. Seine Flexibilität (über 300 Komponenten) und Erweiterbarkeit (z. B. mit Groovy oder Java) machen es zur idealen Wahl für anspruchsvolle Integrationsaufgaben mit Microsoft Entra ID und anderen Cloud-Diensten.

Nächste Schritte: Deine eigene Integration umsetzen

Die hier vorgestellten Best Practices und Code-Beispiele findest du auf GitHub:

👉 GitHub-Repository: Camel & Microsoft Entra ID-Integration

Klone das Repository, passe die application.properties an und starte deine Route mit:

camel run application.properties auth-handler.camel.yaml list-group-members.camel.yaml

Du möchtest mehr über Apache Camel erfahren?

  • Experimentiere mit den Beispielen und passe sie an deine Microsoft 365-Umgebung an.
  • Folge unserem Blog.
  • Brauchst du Unterstützung? Wir helfen dir gerne bei der Umsetzung deiner Camel-Integration – von der Konzeption bis zum Betrieb. Kontaktiere uns für eine kostenlose Erstberatung.

Mit den hier vorgestellten Techniken und Tools (wie Kaoto oder Camel Karavan) bist du nun bestens gerüstet, um eigene Integrationslösungen zu entwickeln – ob für Microsoft Entra ID, Azure AD oder andere API-basierte Systeme. Viel Erfolg bei deinen Projekten!

Back to Blog

Related Posts

View All Posts »

Systemintegration muss nicht teuer sein

Viele Unternehmen scheuen vor Systemintegration zurück – aus Angst vor hohen Kosten und komplexer Umsetzung. Der Artikel zeigt, wie das Open-Source-Framework Apache Camel eine kostengünstige, flexible und zukunftssichere Lösung bietet. Mit standardisierten Integrationsmustern, hoher Wiederverwendbarkeit und einfacher Wartung ermöglicht Camel auch kleinen und mittleren Unternehmen den Einstieg in eine professionelle Integrationsarchitektur – ohne Vendor-Lock-in oder Lizenzkosten.