[JAVA] Envoyez une demande au backend après une authentification unique avec Spring Cloud Gateway

Objectif

Pour divers outils de l'interface utilisateur Web tels que Locust qui peuvent être utilisés sans authentification de l'utilisateur Je voulais l'utiliser après avoir inséré ma propre authentification. J'ai trouvé difficile d'implémenter la fonction d'authentification dans chaque outil à mesure que les types d'outils augmentaient.

Par conséquent, placez l'application Spring Cloud Gateway devant chaque outil. Ici, nous acceptons toutes les demandes pour chaque outil, effectuons notre propre authentification et Si l'authentification est OK, j'ai essayé d'envoyer la demande à l'outil backend.

Configuration du projet

Ajoutez "Gateway" aux dépendances dans Spring initializr, créez un modèle et téléchargez-le.

Implémentation 1: tout d'abord, demandez la distribution sans authentification

Tout d'abord, sans la fonction d'authentification, acceptez simplement la demande avec Sprin Cloud Gateway, Essayons de distribuer la demande à l'outil backend.

Jusqu'à présent, il n'est pas nécessaire d'implémenter des classes Java, et cela peut être réalisé simplement en définissant application.yaml.

Cette fois, l'application Spring Cloud Gateway écoute sur le port 8080 et http://localhost:8080 Rendez-le accessible avec.

L'URL de l'outil d'interface utilisateur Web backend est http://localhost:9001 et http://localhost:9002 ça ira.

application.yaml

#Paramètres de numéro de port de Spring Cloud Gateway(Tu n'as pas à)
server:
  port: 8080

#Paramètres principaux de Spring Cloud Gateway
spring:
  cloud:
    gateway:
      routes:
        # -----------------------------------------------------
        # http://localhost:8080/tool1/hoge/fuga/...Demande
        # http://localhost:9001/hoge/fuga/...Flux vers
        # -----------------------------------------------------
        - id: tool1
          #Destination proxy
          uri: http://localhost:9001
          #routage
          predicates:
            - Path=/tool1/**
          #filtre(Insérer la réécriture de chemin et le traitement original)
          filters:
            - StripPrefix=1 #Coupez le début du chemin. Dans ce cas"/tool1"Se débarrasser de
        # -----------------------------------------------------
        # http://localhost:8080/tool2/hoge/fuga/...Demande
        # http://localhost:9002/hoge/fuga/...Flux vers
        # -----------------------------------------------------
        - id: tool2
          #Destination proxy
          uri: http://localhost:9002
          #routage
          predicates:
            - Path=/tool2/**
          #filtre(Insérer la réécriture de chemin et le traitement original)
          filters:
            - StripPrefix=1 #Coupez le début du chemin. Dans ce cas"/tool2"Se débarrasser de

L'important est spring.cloud.gateway.routes, et le contour de chaque élément est le suivant

article Contenu
id Définissez n'importe quel ID
uri Pour envoyer la demande(Back end)Mettre en place
predicates Définissez le type de demande adressée à Spring Cloud Gateway à appliquer à cette règle de routage.
filters Spécifiez lors de l'insertion du traitement avant ou après l'envoi d'une requête au backend. Vous pouvez également utiliser votre propre classe de filtre(Voir ci-dessous)

Veuillez vous reporter au Document officiel de Spring Cloud Gateway pour découvrir quels sont les prédicats et filtres intégrés. Je pense.

Contrôle de fonctionnement

Au lieu de l'outil WebUI réel, lancez un serveur stub qui renvoie une chaîne fixe avec la commande nc.

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

Envoyez ensuite une requête curl à Spring Cloud Gateway.

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

Si les paramètres de Spring Cloud Gateway sont corrects, localhost: 8080 / tool1 / hoge / fuga request Il doit être transféré vers localhost: 9001 / hoge / fuga.

résultat

Le contenu de la demande envoyée au serveur stub est le suivant. Vous pouvez voir que le chemin de l'URL est / hoge / fuga au lieu de / tool / hoge / fuga.

$ (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

Le résultat de la requête curl est le suivant Vous pouvez voir que Spring Cloud Gateway renvoie la réponse du serveur stub sur le back-end.

$ 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

Implémentation 2: ajoutez votre propre filtre pour vous authentifier

Ensuite, créez votre propre filtre d'authentification et appliquez-le. Cette fois, extrayez la valeur de la clé "Authorization" de l'en-tête de la requête HTTP Si la valeur est "xxx", l'authentification est OK et une demande est envoyée au backend. Sinon, essayez de créer un filtre qui renvoie une réponse 401 Unauthorizaed comme authentification NG.

MyAuthFilter.java L'implémentation du filtre est la suivante et implémente une classe qui hérite de AbstractGatewayFilterFactory.

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

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            //Obtenir l'en-tête d'autorisation
            ServerHttpRequest request = exchange.getRequest();
            String authorizationHeader = Optional.ofNullable(request.getHeaders().get("Authorization"))
                    .map(h -> {return h.get(0);}).orElse("");

            //Si l'en-tête d'autorisation est xxx, la demande sera envoyée telle quelle avec une authentification réussie.
            //Sinon renvoie une réponse 401 non autorisée
            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 La création de votre propre classe de filtre comme décrit ci-dessus ne sera pas encore reflétée. Si vous souhaitez appliquer votre propre filtre, accédez à l'élément filtres dans application.yaml. J'écrirai le nom de classe de ce filtre unique.

L'image entière de application.yaml est la suivante, et seules les deux lignes qui disent "[Ajouter]" sont ajoutées.

#Paramètres principaux de Spring Cloud Gateway
spring:
  cloud:
    gateway:
      routes:
        # -----------------------------------------------------
        # http://localhost:8080/tool1/hoge/fuga/...Demande
        # http://localhost:9001/hoge/fuga/...Flux vers
        # -----------------------------------------------------
        - id: tool1
          #Destination proxy
          uri: http://localhost:9001
          #routage
          predicates:
            - Path=/tool1/**
          #filtre(Insérer la réécriture de chemin et le traitement original)
          filters:
            - MyAuthFilter  # [ajouter à]Insérez votre propre filtre d'authentification
            - StripPrefix=1 #Coupez le début du chemin. Dans ce cas"/tool1"Se débarrasser de
        # -----------------------------------------------------
        # http://localhost:8080/tool2/hoge/fuga/...Demande
        # http://localhost:9002/hoge/fuga/...Flux vers
        # -----------------------------------------------------
        - id: tool2
          #Destination proxy
          uri: http://localhost:9002
          #routage
          predicates:
            - Path=/tool2/**
          #filtre(Insérer la réécriture de chemin et le traitement original)
          filters:
            - MyAuthFilter  # [ajouter à]Insérez votre propre filtre d'authentification
            - StripPrefix=1 #Coupez le début du chemin. Dans ce cas"/tool2"Se débarrasser de

#Paramètres de numéro de port de Spring Cloud Gateway(Tu n'as pas à)
server:
  port: 8080

Contrôle de fonctionnement

Lancez le serveur stub sur le port 9001 comme précédemment, Demande sans en-tête d'autorisation comme ci-dessous Faites une demande curl avec un en-tête d'autorisation.

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

résultat

Si vous demandez sans l'en-tête Authrozation, tel qu'implémenté dans MyAuthFilter, Une réponse 401 non autorisée est renvoyée.

$ 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
<

Vous pouvez également voir qu'aucune demande n'est arrivée du côté du serveur de stub.

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

Ensuite, lorsque vous demandez en définissant la valeur de xxx dans l'en-tête Authrozation, La chaîne hello retournée par le serveur stub est renvoyée.

$ 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

Vous pouvez voir que la demande arrive également du côté du serveur de stub.

$ (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

Pour le moment, il semble que cela puisse être réalisé en jugeant si l'authentification est OK ou NG et en contrôlant s'il faut ou non envoyer une requête au back-end.

référence

site Aperçu
Jouez avec Spring Cloud Gateway Première page lue
Spring Cloud Gateway Documentation officielle du printemps. Il existe de nombreuses informations sur les prédicats et les filtres intégrés. Il y a aussi une petite explication sur le filtre auto-fabriqué.
Spring Cloud Gateway - Creating Custom Route Filters (AbstractGatewayFilterFactory) Mise en œuvre d'un filtre et d'une application personnalisés.Pour la méthode de paramétrage avec yaml, je me suis principalement référé à cette page.

Recommended Posts

Envoyez une demande au backend après une authentification unique avec Spring Cloud Gateway
Envoyer une pull request à GitHub
Authentification Oauth2 avec Spring Cloud Gateway
Configurer des microservices avec Spring Cloud (4): API Gateway
Comment vérifier avant d'envoyer un message au serveur avec Spring Integration
03. J'ai envoyé une demande de Spring Boot à l'API de recherche de code postal
Envoyez des notifications à Slack avec la version gratuite de sentry (en utilisant lambda)
Écrivons une fonction Lambda qui intègre Amazon API Gateway à Spring Cloud Function.
[Rails] Traitement après l'ajout d'une colonne à la table de devise
Comment faire une capture d'écran avec l'émulateur Android Studio
Comment demander un fichier CSV au format JSON avec jMeter
La première application WEB avec Spring Boot-Making a Pomodoro timer-
Pour recevoir une demande vide avec Spring Web MVC @RequestBody
J'ai essayé d'exprimer les résultats avant et après de la classe Date avec une ligne droite numérique
Essayez d'imiter l'idée d'un tableau à deux dimensions avec un tableau à une dimension
Je veux comprendre le flux des paramètres de demande de traitement Spring
Lisez le fichier sous le chemin de classe sous forme de chaîne de caractères avec ressort
Logique pour dessiner un cercle sur la console avec l'art ASCII
Connexion à une base de données avec Java (partie 1) Peut-être la méthode de base
Remplacer par une valeur selon la correspondance avec une expression régulière Java
Exemple de code pour le test unitaire d'un contrôleur Spring Boot avec MockMvc
Connectez les appareils IoT au cloud à l'aide de scénarios de passerelle et de sous-appareil
Je voulais faciliter la programmation JavaFX avec Spring Framework
Choses à oublier lors de l'interception d'une requête avec Android WebView # shouldInterceptRequest