Рубрики
Без рубрики

AUTH0 с плагином Kong JWT в Docker – простой гид с сценариями Python

Kong и AUTH0 – очень мощные платформы. Конечно, чем больше вы можете сделать с инструментом, тем больше Doc … Tagged с AUTH0, Docker, Python, Kong.

Конг и AUTH0 очень мощные платформы. Конечно, чем больше вы можете сделать с инструментом, тем больше документации вам нужно прочитать, а иногда это может быть расстраивает 😬

Итак, я создал это руководство, чтобы показать, как вы можете легко настроить все в местной среде и играть в любом случае.

Чтобы сохранить эту статью коротко, я предполагал, что вы уже немного знаете о Docker, Kong и Auth0. В любом случае здесь есть некоторые ссылки:

Кроме того, вам понадобится три вещи, чтобы следовать этому руководству:

  • API вы можете использовать для тестирования;
  • AUTH0 Account/арендатор, где вы можете генерировать токен доступа;
  • IDE для запуска сценариев Python (я использую Pycharm);

Я использую сценарии Python в качестве примера того, как вы можете автоматизировать процесс конфигурации. Это может быть большая помощь для тех, кому нужно настроить Kong для бегущей системы или другой среды.

Первые вещи в первую очередь!

Давайте начнем с кона, работающего в контейнере докера.

Нам нужно создать докеровную сеть и базу данных для Kong:

docker network create kong-net
docker run -d --name kong-database \
               --network=kong-net \
               -p 5432:5432 \
               -e "POSTGRES_USER=kong" \
               -e "POSTGRES_DB=kong" \
               -e "POSTGRES_PASSWORD=kong" \
               postgres:9.6

Миграция базы данных:

docker run --rm \
     --network=kong-net \
     -e "KONG_DATABASE=postgres" \
     -e "KONG_PG_HOST=kong-database" \
     -e "KONG_PG_USER=kong" \
     -e "KONG_PG_PASSWORD=kong" \
     -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
     kong:latest kong migrations bootstrap

И теперь мы можем запустить наш контейнер:

docker run -d --name kong \
     --network=kong-net \
     -e "KONG_DATABASE=postgres" \
     -e "KONG_PG_HOST=kong-database" \
     -e "KONG_PG_USER=kong" \
     -e "KONG_PG_PASSWORD=kong" \
     -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
     -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
     -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
     -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
     -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
     -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
     -p 8000:8000 \
     -p 8443:8443 \
     -p 127.0.0.1:8001:8001 \
     -p 127.0.0.1:8444:8444 \
     kong:latest

Попробуйте сделать тест:

curl -i http://localhost:8001/

Если у вас есть некоторые проблемы, проверьте, работают ли ваши контейнеры:

docker ps

Если вы не видите Конг и Kong-база данных Контейнеры в списке, то вам нужно будет запустить их явно:

docker start kong kong-database 

Вы также можете использовать почтальон для тестирования:

Время для некоторых сценариев!

Кстати, используя Python не является обязательным. Если вам это не нравится, вы все равно можете следить за этими шагами с любым другим языком или использовать команды Curl.

Давайте сначала определим объект конфигурации для нашей новой службы и маршрута.

# you'll need those imports later
import requests
import json

host = "192.168.1.98"

config = {
    "service": {
        "name": "test-service",
        "url": "http://" + host + ":7400/api/test/data",
    },
    "route": {
        "protocols": ["http"],
        "methods": ["GET", "POST", "PUT", "DELETE"],
        "hosts": [host],
        "paths": ["/(data)/*"],
        "headers": None,
    },
}

Здесь Service.url это место, где Kong будет перенаправлять нас, если мы позвоним localhost: 8000/data с заголовком Хозяин 192.168.1.98 (теоретически 🙃).

Если вы не хотите использовать локальные API, то вы можете изменить Service.url и Route.hosts использовать ваши значения. В противном случае держу пари, у вас возникнет вопрос: «Почему 192.168.1.98 и не локальный?» . Держите эту мысль, я вернусь к этому.

Следующий шаг – создание обслуживания и маршрута в Конг.

Прежде всего, скопируйте этот скрипт в один и тот же файл, где у вас есть объект конфигурации и внимательно посмотрите, что там происходит. Не беги еще – нам все еще нужно проверить еще одну вещь.

# create a service using our config object
print(config["service"]["name"])
serviceUrl = "http://localhost:8001/services"

serviceResponse = requests.post(url=serviceUrl, json=config["service"])

# print service id to ensure that it was successfully created 
serviceId = (json.loads(serviceResponse.content))["id"]
print("serviceId ", serviceId)

# create a route using our config object
routeUrl = "http://localhost:8001/routes"

config["route"]["service"] = {
    "id": serviceId
}

routeResponse = requests.post(url=routeUrl, json=config["route"])
routeId = (json.loads(routeResponse.content))["id"]

# print route id because you'll need it to add a plugin later
print("routeId", routeId)

И теперь – почему мы используем «192.168.1.98», а не локальным для нашего сервиса.

Я играю вокруг, пытаясь прокси мою местную услугу с Kong работает в докеренном контейнере. Когда я позвонил My Local API через Kong, он продолжал возвращать 502 ошибку с сообщением Неверный ответ был получен от восходящего сервера Отказ

Причина в том, что Конг был указан на localhost моего контейнера докера. Очевидно, что не сработало, потому что мой сервис там не был проведен.

Конечно, вам не нужно заботиться об этом, если вы используете внешние API для тестирования.

Легкое решение здесь состоит в том, чтобы зарегистрировать свою службу KONG с IP-адресом локального хостамата (например, 192.168.1.98). Кстати, это будет отличаться для вашей машины. Вероятно, вы можете проверить это. Беги /sbin/ifconfig для Mac или ipconfig Для Windows Machine.

Вы должны быть в состоянии увидеть такой SMTH:

Не забудьте обновить хозяин В Python Config с вашим IP и имею в виду, что он должен отличаться от использования одного KONG.

Хорошо, и теперь вы можете попробовать запустить свой скрипт. Если вы не видите ошибки в выходе IDE, вы можете попытаться получить список сервисов или маршрутов (просто чтобы убедиться, что они действительно созданы).

Теперь, если вам повезет, вы сможете получить доступ к вашему API напрямую или через Конг. Примечание. Ваш API должен быть запущен и работает.

Прямой запрос:

Запрос через Конг:

Последний шаг. Давайте сделаем это безопасным!

У меня уже был открытый ключ для моей учетной записи AUTH0, но если у вас его нет, то выполните команды ниже и сохраните файл с открытым ключом в том же каталоге с помощью сценария Python.

Примечание: не забудьте заменить эти значения {CompanyName}. {Region-ID}

Вам нужно будет загрузить сертификат вашей учетной записи AUTH0:

$ curl -o {COMPANYNAME}.pem https://{COMPANYNAME}.{REGION-ID}.auth0.com/pem

И извлечь открытый ключ от сертификата X509:

$ openssl x509 -pubkey -noout -in {COMPANYNAME}.pem > pubkey.pem

Здорово! Теперь нам нужно добавить плагин jwt и потребителя

Если вы забыли сохранить ваш поставщик, то вы можете запросить его из http://localhost: 8001/маршруты (Найдите свой маршрут, если у вас есть более одного) и скопируйте свой идентификатор из ответа.

# create a plugin for our route
# here you'll need to insert your routeId
pluginUrl = "http://localhost:8001/routes/" + {ROUTEID} + "/plugins"

pluginData = {
    "name": "jwt"
}

requests.post(url=pluginUrl, json=pluginData)

Примечание. Сценарий не будет работать, если вы забыли поставить свой открытый ключ в той же папке.

# create a global consumer
consumerUrl = "http://localhost:8001/consumers"
consumerData = {
    "username": "test-consumer",
    "custom_id": "test-consumer-id",
}

consumerResponse = requests.post(url=consumerUrl, json=consumerData)

# print consumer id to ensure that it was successfully created
consumerId = (json.loads(consumerResponse.content))["id"]
print("consumerId ", consumerId)

# Add JWT plugin with Auth0 public key
basicUrl = consumerUrl + "/" + consumerId + "/jwt"
basicData = {
    "algorithm": "RS256",
    "key": "https://{COMPANYNAME}.{REGION-ID}.auth0.com/",
    "rsa_public_key": open('pubkey.pem', 'rb')
}

requests.post(url=basicUrl, files=basicData)

Vualá 🥳.

Теперь вы не сможете позвонить вам через Kong без токена носителя. Кроме того, только токены, подписанные AUTH0.

Вы можете попытаться сделать тот же звонок localhost: 8000/data И, если вы сделали все правильно, вы должны получить 401 Несанкционировано Отказ Заголовок Хозяин 192.168.1.98 следует прикрепить к запросу, когда вы звоните в Конг.

Когда токен предъявителя прикреплен, ваш запрос должен быть принят:

Еще несколько вещей

  1. Если вам нужно проверить Scopes или претензий в своем токене, и вы используете версию Kong Enterprise, вы можете взглянуть на плагин JWT Signer. Этот плагин проверит и (повторный) токен знак для вас.

  2. Если у вас есть, например, приложение SPA, которое должно получить доступ к нескольким API, вы можете проверить эту тему из документации AUHT0 Представляют несколько API с использованием одного логического API Отказ

  3. Если у вас есть Kong, и все ваши API защищены им и доверяют, вам не нужно генерировать токены M2M. Конечно, если вам это нужно или найти это ценным, то уверена, иди на это. Это просто то, о чем вы должны подумать, это действительно сделает вашу систему более безопасной или просто принесет ненужные расходы?

Спасибо!

Я надеюсь, что это руководство было полезным. Спасибо за чтение. Не стесняйтесь обращаться ко мне, задавайте вопросы или дайте мне знать, если вы нашли ошибку 🤗

Оригинал: “https://dev.to/borzenko_lena/auth0-with-kong-jwt-plugin-in-docker-simple-guide-with-python-scripts-49le”