Apache APISIX s'intègre à Open Policy Agent pour enrichir son écosystème

API7.ai

December 24, 2021

Ecosystem

Open Policy Agent (OPA) est un moteur de politique open source léger et polyvalent qui peut remplacer le module de fonction de politique intégré dans les logiciels et aider les utilisateurs à découpler les services du moteur de politique. Grâce à l'écosystème bien établi d'OPA, les utilisateurs peuvent facilement intégrer OPA avec d'autres services, tels que des bibliothèques de programmes, des API HTTP, etc.

Comme illustré dans la figure ci-dessous, OPA décrit d'abord la politique via le langage de politique Rego ; puis stocke les données de politique via JSON, après quoi l'utilisateur peut envoyer une requête de consultation. Après avoir reçu la requête de consultation, OPA combinera la politique, les données et l'entrée de l'utilisateur pour générer une décision de politique et envoyer cette décision au service.

Workflow OPA

Introduction au Plugin

Apache APISIX fournit un plugin opa qui permet aux utilisateurs d'introduire facilement les capacités de politique fournies par OPA dans Apache APISIX pour activer des fonctionnalités d'authentification et de contrôle d'accès flexibles.

Après avoir configuré le plugin opa sur une route, Apache APISIX assemble les informations de requête, les informations de connexion, etc. en données JSON et les envoie à l'adresse de l'API de décision de politique lors du traitement des requêtes de réponse. Tant que la politique déployée dans OPA est conforme à la spécification de données définie par Apache APISIX, des fonctions telles que passer la requête, rejeter la requête, personnaliser le code d'état, personnaliser l'en-tête de réponse, etc. peuvent être implémentées.

Cet article prend l'API HTTP comme exemple pour présenter le plugin opa et détaille comment intégrer Apache APISIX avec OPA pour découpler l'authentification et l'autorisation des services back-end.

Comment utiliser

Construire l'environnement de test

  1. Utiliser Docker pour construire les services OPA.

    # Exécuter OPA avec Docker
    docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
    
  2. Créer une politique example.

    # Créer une politique
    curl -XPUT 'localhost:8181/v1/policies/example' \
    --header 'Content-Type: text/plain' \
    --data-raw 'package example
    
    import input.request
    import data.users
    
    default allow = false
    
    allow {
        # a l'en-tête de requête test-header avec la valeur only-for-test
        request.headers["test-header"] == "only-for-test"
        # La méthode de requête est GET
        request.method == "GET"
        # Le chemin de requête commence par /get
        startswith(request.path, "/get")
        # Le paramètre GET test existe et n'est pas égal à abcd
        request.query["test"] != "abcd"
        # Le paramètre GET user existe
        request.query["user"]
    }
    
    reason = users[request.query["user"]].reason {
        not allow
        request.query["user"]
    }
    
    headers = users[request.query["user"]].headers {
        not allow
        request.query["user"]
    }
    
    status_code = users[request.query["user"]].status_code {
        not allow
        request.query["user"]
    }'
    
  3. Créer des données users.

    # Créer des données de test utilisateur
    curl -XPUT 'localhost:8181/v1/data/users' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "alice": {
            "headers": {
                "Location": "http://example.com/auth"
            },
            "status_code": 302
        },
        "bob": {
            "headers": {
                "test": "abcd",
                "abce": "test"
            }
        },
        "carla": {
            "reason": "Give you a string reason"
        },
        "dylon": {
            "headers": {
                "Content-Type": "application/json"
            },
            "reason": {
                "code": 40001,
                "desc": "Give you a object reason"
            }
        }
    }'
    

Créer une route et activer le plugin

Exécutez la commande suivante pour créer la route et activer le plugin opa.

curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r1' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "uri": "/*",
    "methods": [
        "GET",
        "POST",
        "PUT",
        "DELETE"
    ],
    "plugins": {
        "opa": {
            "host": "http://127.0.0.1:8181",
            "policy": "example"
        }
    },
    "upstream": {
        "nodes": {
            "httpbin.org:80": 1
        },
        "type": "roundrobin"
    }
}'

Tester les requêtes

Ensuite, exécutez la commande suivante pour envoyer une requête au plugin opa afin de tester l'état de fonctionnement du plugin.

# Autoriser les requêtes
curl -XGET '127.0.0.1:9080/get?test=none&user=dylon' \
    --header 'test-header: only-for-test'
{
    "args": {
        "test": "abcd1",
        "user": "dylon"
    },
    "headers": {
        "Test-Header": "only-for-test",
        "with": "more"
    },
    "origin": "127.0.0.1",
    "url": "http://127.0.0.1/get?test=abcd1&user=dylon"
}

# Rejeter la requête et réécrire le code d'état et les en-têtes de réponse
curl -XGET '127.0.0.1:9080/get?test=abcd&user=alice' \
    --header 'test-header: only-for-test'

HTTP/1.1 302 Moved Temporarily
Date: Mon, 20 Dec 2021 09:37:35 GMT
Content-Type: text/html
Content-Length: 142
Connection: keep-alive
Location: http://example.com/auth
Server: APISIX/2.11.0

# Rejeter la requête et retourner un en-tête de réponse personnalisé
curl -XGET '127.0.0.1:9080/get?test=abcd&user=bob' \
    --header 'test-header: only-for-test'

HTTP/1.1 403 Forbidden
Date: Mon, 20 Dec 2021 09:38:27 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 150
Connection: keep-alive
abce: test
test: abcd
Server: APISIX/2.11.0

# Rejeter la requête et retourner une réponse personnalisée (chaîne)
curl -XGET '127.0.0.1:9080/get?test=abcd&user=carla' \
    --header 'test-header: only-for-test'

HTTP/1.1 403 Forbidden
Date: Mon, 20 Dec 2021 09:38:58 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.11.0

Give you a string reason

# Rejeter la requête et retourner une réponse personnalisée (JSON)
curl -XGET '127.0.0.1:9080/get?test=abcd&user=dylon' \
    --header 'test-header: only-for-test'

HTTP/1.1 403 Forbidden
Date: Mon, 20 Dec 2021 09:42:12 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.11.0

{"code":40001,"desc":"Give you a object reason"}

Désactiver le plugin

Grâce à la nature dynamique d'Apache APISIX, le plugin OPA sur une route peut être désactivé simplement en supprimant la configuration liée au plugin opa de la configuration de la route et en la sauvegardant.

Résumé

Cet article décrit les étapes détaillées pour interfacer Apache APISIX et Open Policy Agent. Nous espérons que cet article vous donnera une compréhension plus claire de l'utilisation d'Open Policy Agent dans Apache APISIX et facilitera les opérations pratiques ultérieures.

Apache APISIX ne se contente pas de maintenir ses propres performances élevées, mais accorde également une grande importance à la construction de son écosystème open source. Actuellement, Apache APISIX dispose de plus de 10 plugins liés à l'authentification et à l'autorisation qui prennent en charge l'interfaçage avec les principaux services d'authentification et d'autorisation de l'industrie.

Si vous avez besoin d'interfacer avec d'autres autorités d'authentification, visitez le GitHub d'Apache APISIX et laissez vos suggestions via issue ; ou abonnez-vous à la liste de diffusion d'Apache APISIX pour exprimer vos idées par e-mail.

Tags: