Apache APISIX se integra con Open Policy Agent para enriquecer su ecosistema

API7.ai

December 24, 2021

Ecosystem

Open Policy Agent (OPA) es un motor de políticas de propósito general ligero y de código abierto que puede reemplazar el módulo de función de políticas integrado en el software y ayudar a los usuarios a desacoplar los servicios del motor de políticas. Gracias al ecosistema bien establecido de OPA, los usuarios pueden integrar fácilmente OPA con otros servicios, como bibliotecas de programas, APIs HTTP, etc.

Como se muestra en la siguiente figura, OPA primero describe la política a través del lenguaje de políticas Rego; luego almacena los datos de la política en JSON, después de lo cual el usuario puede enviar una solicitud de consulta. Al recibir la solicitud de consulta, OPA combinará la política, los datos y la entrada del usuario para generar una decisión de política y enviar la decisión al servicio.

Flujo de trabajo de OPA

Introducción al Plugin

Apache APISIX proporciona un plugin opa que permite a los usuarios introducir convenientemente las capacidades de políticas proporcionadas por OPA en Apache APISIX para habilitar funciones flexibles de autenticación y control de acceso.

Después de configurar el plugin opa en una ruta, Apache APISIX ensambla la información de la solicitud, la información de la conexión, etc., en datos JSON y los envía a la dirección de la API de decisión de políticas al procesar las solicitudes de respuesta. Siempre que la política implementada en OPA cumpla con la especificación de datos establecida por Apache APISIX, se pueden implementar funciones como permitir la solicitud, rechazar la solicitud, código de estado personalizado, encabezado de respuesta personalizado, etc.

Este artículo toma HTTP API como ejemplo para presentar el plugin opa y detalla cómo integrar Apache APISIX con OPA para desacoplar la autorización de autenticación de los servicios back-end.

Cómo usarlo

Construir el entorno de prueba

  1. Usar Docker para construir servicios OPA.

    # Ejecutar OPA con Docker
    docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
    
  2. Crear una política example.

    # Crear política
    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 {
        # tiene el nombre test-header con el valor only-for-test en el encabezado de la solicitud
        request.headers["test-header"] == "only-for-test"
        # El método de la solicitud es GET
        request.method == "GET"
        # La ruta de la solicitud comienza con /get
        startswith(request.path, "/get")
        # El parámetro GET test existe y no es igual a abcd
        request.query["test"] != "abcd"
        # El parámetro 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. Crear datos users.

    # Crear datos de usuario de prueba
    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"
            }
        }
    }'
    

Crear una ruta y habilitar el plugin

Ejecute el siguiente comando para crear la ruta y habilitar el 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"
    }
}'

Probar solicitudes

A continuación, ejecute el siguiente comando para enviar una solicitud al plugin opa para probar el estado de funcionamiento del plugin.

# Permitir solicitudes
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"
}

# Rechazar la solicitud y reescribir el código de estado y los encabezados de respuesta
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

# Rechazar la solicitud y devolver un encabezado de respuesta personalizado
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

# Rechazar la solicitud y devolver una respuesta personalizada (cadena)
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

# Rechazar la solicitud y devolver una respuesta personalizada (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"}

Deshabilitar el plugin

Gracias a la naturaleza dinámica de Apache APISIX, el plugin OPA en una ruta se puede desactivar simplemente eliminando la configuración relacionada con el plugin opa de la configuración de la ruta y guardándola.

Resumen

Este artículo describe los pasos detallados para la interfaz entre Apache APISIX y Open Policy Agent. Esperamos que este artículo le brinde una comprensión más clara del uso de Open Policy Agent en Apache APISIX y facilite la operación práctica posterior.

Apache APISIX no solo se compromete a mantener su propio alto rendimiento, sino que también siempre ha prestado gran atención a la construcción de un ecosistema de código abierto. Actualmente, Apache APISIX tiene más de 10 plugins relacionados con la autenticación y autorización que admiten la interfaz con los principales servicios de autenticación y autorización de la industria.

Si tiene la necesidad de interactuar con otras autoridades de autenticación, visite el GitHub de Apache APISIX y deje sus sugerencias a través de un issue; o suscríbase a la lista de correo de Apache APISIX para expresar sus ideas por correo electrónico.

Tags: