Direkt zum Hauptinhalt springen

Felix Nehrke

Ich schreibe hier über Softwareentwicklung und Softwarearchitektur.

english

Spring-WebClient für Testumgebungen konfigurieren

Seit einiger Zeit schon liefert Spring einen reactiven Web-client. Dieser Client liefert zwar viele Einstellungen aber nicht alles ist so offensichtlich und einfach. Häufig möchte ich während der Entwicklung zum Beispiel genau sehen, wie der Server antwortet, oder bestimmte Fehler ignorieren. Hierzu möchte ich den Client so konfigurieren, dass ich solche Fehler mitbekommen und entsprechend reagieren kann.

TLS/SSL checks deaktivieren

Gerade bei Testumgebungen begegnen mir immer wieder sehr fragwürdige TLS-Konstruktionen. Im besten Falle werden noch selbst-signierte Zertifikate verwendet, denen man lediglich für den konkreten Fall vertrauen muss. Im schlimmsten Fall jedoch werden hier auch schonmal falsche oder ungültige Zertifikate verwendet. Insbesondere in großen Unternehmen muss man dazu oft noch einer zentralen CA vertrauen und diese überall bekannt machen.

Natürlich sollten diese Missstände sofort adressiert werden, indem wir die Leute über ihre Fehler informieren.

Während die Fehler behoben werden können wir mittels der richtigen Konfiguration trotzdem schon unseren Code ausprobieren. Dazu müssen wir die TLS-Prüfung vom Webclient wie folgt deaktivieren:

SslContext sslContext =
    SslContextBuilder.forClient()
        .trustManager(InsecureTrustManagerFactory.INSTANCE)
        .build(); (1)
HttpClient httpClient = HttpClient.create()
    .secure(t -> t.sslContext(sslContext)); (2)
WebClient webClient =
    WebClient.builder()
        .clientConnector(
            new ReactorClientHttpConnector(httpClient)) (3)
        .build();
1Wir benötigen eine SslContext, welcher durch die InsecureTrustManagerFactory allen Zertifikaten vertraut
2Anschließend können wir einen HttpClient erstellen, der den unsicheren SSL-Context verwendet
3Zuletzt müssen wir noch den WebClient so konfigurieren, dass er den neue HttpClient nutzt

Der so erstellte Webclient ignoriert die meisten TLS-Fehler und ermöglicht uns erstmal weiter die API anzubinden. In den Fällen in denen diese Anpassung nicht ausreicht, um eine Übergangslösung zu schaffen, sollten so oder so alle Alarmglocken schrillen. Sprich dann ist wahrscheinlich viel mehr kaputt, als nur ein Zertifikat.

Diese Einstellung sollte niemals in produktiven Code übernommen werden, da sie TLS komplett ad absurdum führt.

Requests und Responses loggen

Ein ganz anderes Problem zeigt sich häufig erst während der konkreten Entwicklungsarbeit. Nämlich, dass die API scheinbar nicht das tut, was wir erwarten. Da kommt mal JSON, mal XML mal eine CSV, dann wird auf einmal eine ganz andere Struktur zurück gegeben, als wie dachten. Diese Problem sind nervig aber viele Anbieter schaffen es immer wieder, dass die Doku etwas anderes sagt als die API tut.

Um hier nicht komplett im Regen zu stehen und voll und ganz abhängig vom Support zu sein, sehe ich hier immer gerne die übertragenen Daten. Zum Glück kann man dem WebClient beibringen, den gesamten Request und die Response zu loggen. Leider ist diese Einstellung aber wieder nicht so offensichtlich:

HttpClient httpClient = HttpClient.create()
    .wiretap(
        this.getClass().getSimpleName(),
        LogLevel.INFO,
        AdvancedByteBufFormat.TEXTUAL); (1)
WebClient webClient =
    WebClient.builder()
        .clientConnector(
            new ReactorClientHttpConnector(httpClient)) (2)
        .build();
1Wir initialisieren wieder einen HttpClient, welcher angewiesen wird den gesamten Datenverkehr in Text-form zu loggen
2Anschließend müssen wir nur noch den WebClient so konfigurieren, dass er den neue HttpClient nutzt

Der so erstellte Webclient loggt stets alle Request- und Response-Informationen aus.

Diese Einstellung sollte nicht in produktiven Code übernommen werden, da auch sensible Daten, wie Zugangsinformation, geloggt werden.

Abschluss

Wie man sieht kann der WebClient recht umfangreich und sehr flexibel konfiguriert werden. Leider findet ein Teil der Konfiguration jedoch nicht im WebClient-Builder selbst statt. Stattdessen müssen wir den zugrunde liegenden Http-Client anpassen.

Happy debugging.