[JAVA] Senden Sie nach eindeutiger Authentifizierung mit Spring Cloud Gateway eine Anfrage an das Backend

Zweck

Für verschiedene Web-UI-Tools wie Locust, die ohne Benutzerauthentifizierung verwendet werden können Ich wollte es verwenden, nachdem ich meine eigene Authentifizierung eingefügt hatte. Ich fand es mühsam, die Authentifizierungsfunktion in jedem Tool zu implementieren, wenn die Arten von Tools zunahmen.

Platzieren Sie daher die Spring Cloud Gateway-Anwendung vor jedem Tool. Hier akzeptieren wir alle Anfragen für jedes Tool, führen unsere eigene Authentifizierung durch und Wenn die Authentifizierung in Ordnung ist, habe ich versucht, die Anforderung an das Backend-Tool zu senden.

Projektaufbau

Fügen Sie "Gateway" zu Abhängigkeiten in Spring initializr hinzu, erstellen Sie eine Vorlage und laden Sie sie herunter.

Implementierung 1: Fordern Sie zunächst die Verteilung ohne Authentifizierung an

Akzeptieren Sie zunächst ohne die Authentifizierungsfunktion einfach die Anforderung mit Sprin Cloud Gateway. Versuchen wir, die Anforderung an das Backend-Tool zu verteilen.

Bis zu diesem Punkt müssen keine Java-Klassen implementiert werden. Dies kann einfach durch Festlegen von application.yaml erreicht werden.

Diesmal überwacht die Spring Cloud Gateway-Anwendung Port 8080 und http://localhost:8080 Machen Sie es zugänglich mit.

Die URL des Backend-Web-UI-Tools lautet http://localhost:9001 und http://localhost:9002 Wird besorgt.

application.yaml

#Einstellungen für die Portnummer des Spring Cloud Gateway(Das musst du nicht)
server:
  port: 8080

#Haupteinstellungen von Spring Cloud Gateway
spring:
  cloud:
    gateway:
      routes:
        # -----------------------------------------------------
        # http://localhost:8080/tool1/hoge/fuga/...Anfrage
        # http://localhost:9001/hoge/fuga/...Fließen zu
        # -----------------------------------------------------
        - id: tool1
          #Proxy-Ziel
          uri: http://localhost:9001
          #Routing
          predicates:
            - Path=/tool1/**
          #Filter(Fügen Sie das Umschreiben des Pfads und die ursprüngliche Verarbeitung ein)
          filters:
            - StripPrefix=1 #Schneiden Sie den Anfang des Pfades ab. In diesem Fall"/tool1"Beseitigen, abschütteln
        # -----------------------------------------------------
        # http://localhost:8080/tool2/hoge/fuga/...Anfrage
        # http://localhost:9002/hoge/fuga/...Fließen zu
        # -----------------------------------------------------
        - id: tool2
          #Proxy-Ziel
          uri: http://localhost:9002
          #Routing
          predicates:
            - Path=/tool2/**
          #Filter(Fügen Sie das Umschreiben des Pfads und die ursprüngliche Verarbeitung ein)
          filters:
            - StripPrefix=1 #Schneiden Sie den Anfang des Pfades ab. In diesem Fall"/tool2"Beseitigen, abschütteln

Das Wichtigste ist spring.cloud.gateway.routes, und der Umriss jedes Elements ist wie folgt

Artikel Inhalt
id Stellen Sie eine beliebige ID ein
uri Um die Anfrage zu senden(Backend)Einstellen
predicates Definieren Sie, welche Art von Anforderung an Spring Cloud Gateway gestellt wird, um diese Routing-Regel anzuwenden.
filters Geben Sie an, wann die Verarbeitung vor oder nach dem Senden einer Anforderung an das Backend eingefügt werden soll. Sie können auch Ihre eigene Filterklasse verwenden(Siehe unten)

Weitere Informationen zu den integrierten Prädikaten und Filtern finden Sie im Offiziellen Dokument zum Spring Cloud Gateway. Ich denke.

Funktionsprüfung

Starten Sie anstelle des eigentlichen WebUI-Tools einen Stub-Server, der mit dem Befehl nc eine feste Zeichenfolge zurückgibt.

$ (echo "HTTP/1.1 200 ok"; echo; echo "hello") | nc -l 9001

Stellen Sie dann eine Curl-Anfrage an Spring Cloud Gateway.

$ curl -v http://localhost:8080/tool1/hoge/fuga

Wenn die Einstellungen für das Spring Cloud Gateway korrekt sind, localhost: 8080 / tool1 / hoge / fuga Anfrage Es sollte zu localhost fließen: 9001 / hoge / fuga.

Ergebnis

Der Inhalt der Anforderung, die an den Stub-Server gesendet wurde, lautet wie folgt. Sie können sehen, dass der URL-Pfad / hoge / fuga anstelle von / tool / hoge / fuga lautet.

$ (echo "HTTP/1.1 200 ok"; echo; echo "hello") | nc -l 9001
GET /hoge/fuga HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.64.1
Accept: */*
Forwarded: proto=http;host="localhost:8080";for="0:0:0:0:0:0:0:1:50024"
X-Forwarded-For: 0:0:0:0:0:0:0:1
X-Forwarded-Proto: http
X-Forwarded-Prefix: /tool1
X-Forwarded-Port: 8080
X-Forwarded-Host: localhost:8080
content-length: 0

Das Ergebnis der Curl-Anforderung ist wie folgt Sie können sehen, dass Spring Cloud Gateway die Antwort des Stub-Servers im Back-End zurückgibt.

$ curl -v http://localhost:8080/tool1/hoge/fuga
> GET /tool1/hoge/fuga HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< transfer-encoding: chunked
<
hello

Implementierung 2: Fügen Sie zur Authentifizierung einen eigenen Filter hinzu

Erstellen Sie als Nächstes Ihren eigenen Authentifizierungsfilter und wenden Sie ihn an. Extrahieren Sie dieses Mal den Wert des Schlüssels "Authorization" aus dem HTTP-Anforderungsheader Wenn der Wert "xxx" ist, ist die Authentifizierung in Ordnung und eine Anforderung wird an das Backend gesendet. Versuchen Sie andernfalls, einen Filter zu erstellen, der eine nicht autorisierte 401-Antwort als Authentifizierungs-NG zurückgibt.

MyAuthFilter.java Die Filterimplementierung lautet wie folgt und implementiert eine Klasse, die AbstractGatewayFilterFactory erbt.

@Component
public class MyAuthFilter extends AbstractGatewayFilterFactory<MyAuthFilter.Config> {
    public MyAuthFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            //Autorisierungsheader abrufen
            ServerHttpRequest request = exchange.getRequest();
            String authorizationHeader = Optional.ofNullable(request.getHeaders().get("Authorization"))
                    .map(h -> {return h.get(0);}).orElse("");

            //Wenn der Autorisierungsheader xxx ist, wird die Anforderung so gesendet, wie sie bei erfolgreicher Authentifizierung ist.
            //Andernfalls wird eine nicht autorisierte 401-Antwort zurückgegeben
            if(authorizationHeader.equals("xxx")) {
                return chain.filter(exchange.mutate().request(request).build());
            } else {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
        };
    }

    public static class Config {

    }
}

application.yaml Das Erstellen einer eigenen Filterklasse wie oben beschrieben wird noch nicht berücksichtigt. Wenn Sie Ihren eigenen Filter anwenden möchten, gehen Sie zum Filterelement in application.yaml. Ich werde den Klassennamen dieses eindeutigen Filters schreiben.

Das gesamte Bild von application.yaml sieht wie folgt aus, und nur die beiden Zeilen mit der Aufschrift "[Hinzufügen]" werden hinzugefügt.

#Haupteinstellungen von Spring Cloud Gateway
spring:
  cloud:
    gateway:
      routes:
        # -----------------------------------------------------
        # http://localhost:8080/tool1/hoge/fuga/...Anfrage
        # http://localhost:9001/hoge/fuga/...Fließen zu
        # -----------------------------------------------------
        - id: tool1
          #Proxy-Ziel
          uri: http://localhost:9001
          #Routing
          predicates:
            - Path=/tool1/**
          #Filter(Fügen Sie das Umschreiben des Pfads und die ursprüngliche Verarbeitung ein)
          filters:
            - MyAuthFilter  # [hinzufügen]Fügen Sie Ihren eigenen Authentifizierungsfilter ein
            - StripPrefix=1 #Schneiden Sie den Anfang des Pfades ab. In diesem Fall"/tool1"Beseitigen, abschütteln
        # -----------------------------------------------------
        # http://localhost:8080/tool2/hoge/fuga/...Anfrage
        # http://localhost:9002/hoge/fuga/...Fließen zu
        # -----------------------------------------------------
        - id: tool2
          #Proxy-Ziel
          uri: http://localhost:9002
          #Routing
          predicates:
            - Path=/tool2/**
          #Filter(Fügen Sie das Umschreiben des Pfads und die ursprüngliche Verarbeitung ein)
          filters:
            - MyAuthFilter  # [hinzufügen]Fügen Sie Ihren eigenen Authentifizierungsfilter ein
            - StripPrefix=1 #Schneiden Sie den Anfang des Pfades ab. In diesem Fall"/tool2"Beseitigen, abschütteln

#Einstellungen für die Portnummer des Spring Cloud Gateway(Das musst du nicht)
server:
  port: 8080

Funktionsprüfung

Starten Sie den Stub-Server wie zuvor an Port 9001. Anfrage ohne Autorisierungsheader wie unten Stellen Sie eine Curl-Anfrage mit einem Authorization-Header.

$ curl -v http://localhost:8080/tool1/hoge/fuga
$ curl -H 'Authorization: xxx' -v http://localhost:8080/tool1/hoge/fuga

Ergebnis

Wenn Sie ohne den in MyAuthFilter implementierten Authrozation-Header anfordern, Eine 401 nicht autorisierte Antwort wird zurückgegeben.

$ curl -v http://localhost:8080/tool1/hoge/fuga
> GET /tool1/hoge/fuga HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< content-length: 0
<

Sie können auch sehen, dass auf der Seite des Stub-Servers keine Anfrage eingegangen ist.

$ (echo "HTTP/1.1 200 ok"; echo; echo "hello") | nc -l 9001
* Keine Änderung

Wenn Sie als Nächstes den Wert von xxx im Authrozation-Header festlegen, Die vom Stub-Server zurückgegebene Hallo-Zeichenfolge wird zurückgegeben.

$ curl -H 'Authorization: xxx' -v http://localhost:8080/tool1/hoge/fuga
> GET /tool1/hoge/fuga HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Authorization: xxx
>
< HTTP/1.1 200 OK
< transfer-encoding: chunked
<
hello

Sie können sehen, dass die Anforderung auch auf der Seite des Stub-Servers eingeht.

$ (echo "HTTP/1.1 200 ok"; echo; echo "hello") | nc -l 9001
GET /hoge/fuga HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.64.1
Accept: */*
Authorization: xxx
Forwarded: proto=http;host="localhost:8080";for="0:0:0:0:0:0:0:1:50517"
X-Forwarded-For: 0:0:0:0:0:0:0:1
X-Forwarded-Proto: http
X-Forwarded-Prefix: /tool1
X-Forwarded-Port: 8080
X-Forwarded-Host: localhost:8080
content-length: 0

Derzeit scheint es möglich zu sein, dies zu realisieren, indem beurteilt wird, ob die Authentifizierung in Ordnung oder nicht OK ist, und gesteuert wird, ob eine Anforderung an das Back-End gesendet werden soll oder nicht.

Referenz

Seite? ˅ Überblick
Spielen Sie mit Spring Cloud Gateway Erste gelesene Seite
Spring Cloud Gateway Offizielle Frühlingsdokumentation. Es gibt viele Informationen zu den integrierten Prädikaten und Filtern. Es gibt auch eine kleine Erklärung zum selbst erstellten Filter.
Spring Cloud Gateway - Creating Custom Route Filters (AbstractGatewayFilterFactory) Implementierung von selbst erstellten Filtern und Anwendungen.Für die Einstellungsmethode mit Yaml habe ich hauptsächlich auf diese Seite verwiesen.

Recommended Posts

Senden Sie nach eindeutiger Authentifizierung mit Spring Cloud Gateway eine Anfrage an das Backend
Senden Sie eine Pull-Anfrage an GitHub
Oauth2-Authentifizierung mit Spring Cloud Gateway
Konfigurieren Sie Microservices mit Spring Cloud (4): API Gateway
So überprüfen Sie, bevor Sie mit Spring Integration eine Nachricht an den Server senden
03. Ich habe eine Anfrage von Spring Boot an die Postleitzahlensuch-API gesendet
Der Name ist und das Alter ist Senden Sie eine Benachrichtigung an Slack mit der Java-freien Version von Sentry (mit Lambda)
Schreiben wir eine Lambda-Funktion, die Amazon API Gateway in die Spring Cloud-Funktion integriert.
[Rails] Verarbeitung nach Hinzufügen einer Spalte zur Entwicklertabelle
So machen Sie einen Screenshot mit dem Android Studio-Emulator
So fordern Sie mit jMeter eine CSV-Datei als JSON an
Die erste WEB-Anwendung mit Spring Boot-Making a Pomodoro Timer-
So erhalten Sie eine leere Anfrage mit Spring Web MVC @RequestBody
Ich habe versucht, die Ergebnisse vor und nach der Date-Klasse mit einer geraden Zahl auszudrücken
Versuchen Sie, die Idee eines zweidimensionalen Arrays mit einem eindimensionalen Array nachzuahmen
Ich möchte den Ablauf der Spring-Verarbeitungsanforderungsparameter verstehen
Lesen Sie die Datei unter dem Klassenpfad als Zeichenfolge mit spring
Logik zum Zeichnen eines Kreises auf der Konsole mit ASCII-Grafik
Herstellen einer Verbindung zu einer Datenbank mit Java (Teil 1) Möglicherweise die grundlegende Methode
Ersetzen Sie durch einen Wert entsprechend der Übereinstimmung mit einem regulären Java-Ausdruck
Beispielcode zum Testen eines Spring Boot-Controllers mit MockMvc
Verbinden Sie IoT-Geräte mithilfe von Gateway- und Subgeräteszenarien mit der Cloud
Ich wollte die JavaFX-Programmierung mit dem Spring Framework vereinfachen
Dinge, die Sie beim Abfangen einer Anfrage mit Android WebView vergessen sollten # shouldInterceptRequest