Apache APISIX integra-se ao Open Policy Agent para enriquecer seu ecossistema

API7.ai

December 24, 2021

Ecosystem

O Open Policy Agent (OPA) é um mecanismo de políticas de propósito geral leve e de código aberto que pode substituir o módulo de função de política integrado em softwares e ajudar os usuários a desacoplar serviços do mecanismo de políticas. Graças ao ecossistema bem estabelecido do OPA, os usuários podem integrar facilmente o OPA com outros serviços, como bibliotecas de programas, APIs HTTP, etc.

Conforme mostrado na figura abaixo, o OPA primeiro descreve a política por meio da linguagem de política Rego; em seguida, armazena os dados da política por meio de JSON, após o que o usuário pode enviar uma solicitação de consulta. Após receber a solicitação de consulta, o OPA combinará a política, os dados e a entrada do usuário para gerar uma decisão de política e enviará a decisão para o serviço.

Fluxo de Trabalho do OPA

Introdução ao Plugin

O Apache APISIX fornece um plugin opa que permite aos usuários introduzir convenientemente as capacidades de política fornecidas pelo OPA no Apache APISIX para habilitar recursos flexíveis de autenticação e controle de acesso.

Após configurar o plugin opa em uma rota, o Apache APISIX monta informações de solicitação, informações de conexão, etc., em dados JSON e os envia para o endereço da API de decisão de política ao processar solicitações de resposta. Desde que a política implantada no OPA esteja em conformidade com a especificação de dados definida pelo Apache APISIX, funções como permitir solicitação, rejeitar solicitação, código de status personalizado, cabeçalho de resposta personalizado, etc., podem ser implementadas.

Este artigo usa a API HTTP como exemplo para introduzir o plugin opa e detalha como integrar o Apache APISIX com o OPA para desacoplar a autorização de autenticação para serviços de back-end.

Como Usar

Construir Ambiente de Teste

  1. Use o Docker para construir serviços OPA.

    # Executando OPA com Docker
    docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
    
  2. Crie uma política example.

    # Criar 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 {
        # tem o cabeçalho test-header com o valor only-for-test
        request.headers["test-header"] == "only-for-test"
        # O método da solicitação é GET
        request.method == "GET"
        # O caminho da solicitação começa com /get
        startswith(request.path, "/get")
        # O parâmetro GET test existe e não é igual a abcd
        request.query["test"] != "abcd"
        # O 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. Crie dados users.

    # Criar dados de usuário de teste
    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"
            }
        }
    }'
    

Criar uma Rota e Habilitar o Plugin

Execute o seguinte comando para criar a rota e habilitar o 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"
    }
}'

Testar Solicitações

Em seguida, execute o seguinte comando para enviar uma solicitação ao plugin opa para testar o status de execução do plugin.

# Permitir solicitações
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"
}

# Rejeitar a solicitação e reescrever o código de status e os cabeçalhos de resposta
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

# Rejeitar a solicitação e retornar um cabeçalho de resposta 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

# Rejeitar a solicitação e retornar uma resposta personalizada (string)
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

# Rejeitar a solicitação e retornar uma resposta 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"}

Desabilitar o Plugin

Graças à natureza dinâmica do Apache APISIX, o plugin OPA em uma rota pode ser desativado simplesmente removendo a configuração relacionada ao plugin opa da configuração da rota e salvando-a.

Resumo

Este artigo descreve os passos detalhados para integrar o Apache APISIX e o Open Policy Agent. Esperamos que este artigo forneça uma compreensão mais clara sobre o uso do Open Policy Agent no Apache APISIX e facilite a operação prática subsequente.

O Apache APISIX não apenas se compromete a manter seu próprio alto desempenho, mas também sempre deu grande importância à construção de um ecossistema de código aberto. Atualmente, o Apache APISIX possui mais de 10 plugins relacionados a autenticação e autorização que suportam a integração com os principais serviços de autenticação e autorização do setor.

Se você tiver a necessidade de integrar com outros serviços de autenticação, visite o GitHub do Apache APISIX e deixe suas sugestões via issue; ou assine a lista de e-mails do Apache APISIX para expressar suas ideias por e-mail.

Tags: