Apache APISIX integriert Open Policy Agent, um sein Ökosystem zu erweitern

API7.ai

December 24, 2021

Ecosystem

Open Policy Agent (OPA) ist eine Open-Source, leichtgewichtige und allgemeine Policy-Engine, die das integrierte Policy-Funktionsmodul in Software ersetzen und Benutzern helfen kann, Dienste von der Policy-Engine zu entkoppeln. Dank OPAs gut etabliertem Ökosystem können Benutzer OPA problemlos mit anderen Diensten wie Programmbibliotheken, HTTP-APIs usw. integrieren.

Wie in der folgenden Abbildung dargestellt, beschreibt OPA zunächst die Policy durch die Policy-Sprache Rego; speichert dann die Policy-Daten in JSON und anschließend kann der Benutzer eine Abfrageanfrage senden. Nach Erhalt der Abfrageanfrage kombiniert OPA die Policy, die Daten und die Benutzereingaben, um eine Policy-Entscheidung zu generieren und diese Entscheidung an den Dienst zu senden.

OPA Workflow

Plugin-Einführung

Apache APISIX bietet ein opa-Plugin, das es Benutzern ermöglicht, die von OPA bereitgestellten Policy-Fähigkeiten bequem in Apache APISIX einzuführen, um flexible Authentifizierungs- und Zugriffskontrollfunktionen zu ermöglichen.

Nach der Konfiguration des opa-Plugins auf einer Route assembliert Apache APISIX bei der Verarbeitung von Antwortanfragen die Anfrageinformationen, Verbindungsinformationen usw. in JSON-Daten und sendet sie an die Policy-Entscheidungs-API-Adresse. Solange die in OPA bereitgestellte Policy den von Apache APISIX festgelegten Datenspezifikationen entspricht, können Funktionen wie das Durchlassen von Anfragen, das Ablehnen von Anfragen, benutzerdefinierte Statuscodes, benutzerdefinierte Antwortheader usw. implementiert werden.

Dieser Artikel verwendet HTTP API als Beispiel, um das opa-Plugin vorzustellen und detailliert, wie Apache APISIX mit OPA integriert werden kann, um die Authentifizierungsautorisierung für Backend-Dienste zu entkoppeln.

Verwendung

Testumgebung erstellen

  1. Verwenden Sie Docker, um OPA-Dienste zu erstellen.

    # OPA mit Docker ausführen
    docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
    
  2. Erstellen Sie eine example-Policy.

    # Policy erstellen
    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 {
        # hat den Namen test-header mit dem Wert only-for-test im Anfrageheader
        request.headers["test-header"] == "only-for-test"
        # Die Anfragemethode ist GET
        request.method == "GET"
        # Der Anfragepfad beginnt mit /get
        startswith(request.path, "/get")
        # Der GET-Parameter test existiert und ist nicht gleich abcd
        request.query["test"] != "abcd"
        # Der GET-Parameter user existiert
        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. Erstellen Sie users-Daten.

    # Testbenutzerdaten erstellen
    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"
            }
        }
    }'
    

Route erstellen und Plugin aktivieren

Führen Sie den folgenden Befehl aus, um die Route zu erstellen und das opa-Plugin zu aktivieren.

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"
    }
}'

Testanfragen

Führen Sie als Nächstes den folgenden Befehl aus, um eine Anfrage an das opa-Plugin zu senden und den Betriebszustand des Plugins zu testen.

# Anfrage erlauben
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"
}

# Anfrage ablehnen und Statuscode und Antwortheader umschreiben
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

# Anfrage ablehnen und benutzerdefinierten Antwortheader zurückgeben
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

# Anfrage ablehnen und benutzerdefinierte Antwort (String) zurückgeben
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

# Anfrage ablehnen und benutzerdefinierte Antwort (JSON) zurückgeben
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"}

Plugin deaktivieren

Dank der dynamischen Natur von Apache APISIX kann das OPA-Plugin auf einer Route deaktiviert werden, indem einfach die opa-Plugin-Konfiguration aus der Routenkonfiguration entfernt und gespeichert wird.

Zusammenfassung

Dieser Artikel beschreibt die detaillierten Schritte zur Integration von Apache APISIX und Open Policy Agent. Wir hoffen, dass dieser Artikel Ihnen ein klareres Verständnis für die Verwendung von Open Policy Agent in Apache APISIX vermittelt und die anschließende praktische Umsetzung erleichtert.

Apache APISIX ist nicht nur bestrebt, seine eigene hohe Leistung aufrechtzuerhalten, sondern legt auch großen Wert auf den Aufbau eines Open-Source-Ökosystems. Derzeit verfügt Apache APISIX über 10+ Authentifizierungs- und Autorisierungs-Plugins, die die Integration mit branchenüblichen Authentifizierungs- und Autorisierungsdiensten unterstützen.

Wenn Sie Bedarf an der Integration mit anderen Authentifizierungsdiensten haben, besuchen Sie das GitHub von Apache APISIX und hinterlassen Sie Ihre Vorschläge über ein Issue; oder abonnieren Sie die Mailingliste von Apache APISIX, um Ihre Ideen per E-Mail zu äußern.

Tags: