Как защитить приложение Flask с помощью Ory Kratos и Ory Keto
16 марта 2022 г.В настоящее время инженерное сообщество имеет множество продуктов для аутентификации в своих рамках. Многие из них имеют встроенные функции для аутентификации и множество библиотек, доступных для входа через социальные сети. У нас есть фреймворк Django, Flask и python-social-auth для создания почти всего, что нам нужно для аутентификации пользователей в мире python.
В этой статье я покажу вам пример того, как добавить все необходимое для аутентификации пользователя без написания большого количества строк кода. Код, используемый в этом сообщении в блоге, доступен на GitHub. Мы будем использовать Flask, flask cookie-cutter, docker, docker-compose, Postgres, Ори Кратос и Ори Кето.
Давайте посмотрим на процесс входа в наше приложение с помощью Ory Kratos и Ory Keto.
[ ] (https://mermaid.live/edit#pako:eNptkktOIzEQhq9S8iojMSIShIUXSIjHCM2CRZRdS1CyK2kraVeP7RYKCGkuMIs5AbsR7DgTJ-AIlNsN0ZB4U9Xu7__rId8rw5aUVpF-deQNnTlcBGwqD3JaDMkZ16JP0EUKgBFmEiOM3h7_Pr3-_vP2-O9F0uch_batWwZMHGeXWfuzz0E-RvrwcDLZgQ_IJ5zBg4Md4HyFcZm5iz4Z6cl4PN5lSIl7uxyz29GRUIXLM30_Pu6tNFy15AGh5oZaXFBBcJVg6hYeLv1-jrO23OfT6zb6H5TghsP6uox8HSlGx_4GDPPS0bauTFiEzpJPLq0hBXQpwjxwA_u3NWPjgLxt2flULGgVCbBLdVYYTGSHe283PZ8YI-XhlH0KvNpRW9ahwdRkZImFlf2I55f5P4txcHdblQa3vEcN05pvY29hpKo0Bzz_zzErim7TTz5qTzUUGnRWHuJ9_lcp0TVUKS2pxbCsVOUfhOtaKwOfW5c4KD1H6W5PSXs8XXujdAodfUDDSx6oh3d7rfx0)
Что мы будем использовать в нашем проекте
- Flask cookiecutter – отличный инструмент для начальной загрузки структуры нашего проекта. Всегда полезно иметь готовые к использованию линтеры, Dockerfile и инструменты управления пакетами из коробки.
- Postgres как СУБД. В этом примере у нас будет две службы Postgres, работающие в двух контейнерах. Я думаю, что это отличная идея — упростить задачу без использования пользовательских сценариев, чтобы иметь несколько баз данных, доступных в одной службе создания докеров.
- Ори Кратос с пользовательским интерфейсом для аутентификации пользователей.
- Ory Keto в качестве службы контроля доступа.
Настройка Ори Кратоса
Ори Кратос будет нести ответственность за хранение идентификационных данных, таких как адрес электронной почты/логин и пароль. С помощью руководства quickstart нам нужно скопировать содержимое contrib/quickstart/kratos/email-password в корень вашего проекта, а затем добавьте в файл docker-compose следующий контент:
```ямл
постгрес-кратос:
изображение: постгрес: 9.6
порты:
- "5432:5432"
окружающая обстановка:
- POSTGRES_USER=кратос
- POSTGRES_PASSWORD=секрет
- POSTGRES_DB=кратос
сети:
- интранет
Кратос-мигрировать:
изображение: oryd/kratos:v0.8.0-alpha.3
ссылки:
- постгрес-кратос:постгрес-кратос
окружающая обстановка:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
сети:
- интранет
тома:
- тип: связать
источник: ./kratos
цель: /etc/config/kratos
команда: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
Кратос:
изображение: oryd/kratos:v0.8.0-alpha.3
ссылки:
- постгрес-кратос:постгрес-кратос
окружающая обстановка:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
порты:
- '4433:4433'
- '4434:4434'
тома:
- тип: связать
источник: ./kratos
цель: /etc/config/kratos
сети:
- интранет
команда: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
Кратос-самообслуживание-UI-узел:
изображение: oryd/kratos-selfservice-ui-node:v0.8.0-alpha.3
окружающая обстановка:
- KRATOS_PUBLIC_URL=http://kratos:4433/
- KRATOS_BROWSER_URL=http://127.0.0.1:4433/
сети:
- интранет
порты:
- "4455:3000"
перезапуск: при сбое
почтальон:
изображение: oryd/mailslurper:latest-smtps
порты:
- '4436:4436'
- '4437:4437'
сети:
- интранет
постгрес-кето:
Настройка Ори Кето
Вы можете ознакомиться с концепциями Ory Keto, прочитав руководство quickstart. Эти статьи могут дать вам краткое введение в него. Поскольку нам нужно управлять доступом к домашней странице, нам нужно создать папку keto
в корне нашего проекта и иметь файл keto/keto.yml
со следующим содержимым:
```ямл
версия: v0.7.0-альфа.1
журнал:
уровень: отладка
пространства имен:
- название: приложение
идентификатор: 1
обслуживать:
читать:
хост: 0.0.0.0
порт: 4466
записывать:
хост: 0.0.0.0
порт: 4467
Нам понадобятся следующие контейнеры:
- postgresd-auth — это база данных для Ory Keto.
- keto-migrate, который заботится о миграции базы данных.
- keto-perms — это оболочка для работы с разрешениями с помощью интерфейса командной строки.
- кето запускает сервер.
```ямл
версия: "3.7"
x-объемы по умолчанию: &default_volumes
тома:
- ./:/приложение
- узлы-модули:/приложение/node_modules
- ./dev.db:/tmp/dev.db
Сервисы:
присягатель:
изображение: oryd/присяга:v0.38
зависит от:
- кратос
порты:
- 8080:4455
- 4456:4456
команда:
служить прокси -c "/etc/config/oathkeeper/oathkeeper.yml"
окружающая обстановка:
- LOG_LEVEL=отладка
перезапуск: при сбое
сети:
- интранет
тома:
- ./присяга:/etc/config/присяга
колба:
строить:
контекст: .
изображение: "kratos_app_example-развитие"
окружающая обстановка:
- FLASK_APP=autoapp.py
- FLASK_ENV=развитие
сети:
- интранет
перезапуск: при сбое
тома:
- тип: связать
источник: ./
цель: /приложение
постгрес-кратос:
изображение: постгрес: 9.6
порты:
- "5432:5432"
окружающая обстановка:
- POSTGRES_USER=кратос
- POSTGRES_PASSWORD=секрет
- POSTGRES_DB=кратос
сети:
- интранет
Кратос-мигрировать:
изображение: oryd/kratos:v0.8.0-alpha.3
ссылки:
- постгрес-кратос:постгрес-кратос
окружающая обстановка:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
сети:
- интранет
тома:
- тип: связать
источник: ./kratos
цель: /etc/config/kratos
команда: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
Кратос:
изображение: oryd/kratos:v0.8.0-alpha.3
ссылки:
- постгрес-кратос:постгрес-кратос
окружающая обстановка:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
порты:
- '4433:4433'
- '4434:4434'
тома:
- тип: связать
источник: ./kratos
цель: /etc/config/kratos
сети:
- интранет
команда: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
Кратос-самообслуживание-UI-узел:
изображение: oryd/kratos-selfservice-ui-node:v0.8.0-alpha.3
окружающая обстановка:
- KRATOS_PUBLIC_URL=http://kratos:4433/
- KRATOS_BROWSER_URL=http://127.0.0.1:4433/
сети:
- интранет
порты:
- "4455:3000"
перезапуск: при сбое
почтальон:
изображение: oryd/mailslurper:latest-smtps
порты:
- '4436:4436'
- '4437:4437'
сети:
- интранет
постгрес-кето:
изображение: постгрес: 9.6
порты:
- "15432:5432"
окружающая обстановка:
- POSTGRES_USER=кето
- POSTGRES_PASSWORD=секрет
- POSTGRES_DB=кето
сети:
- интранет
кето-мигрировать:
изображение: orid/кето:v0.7.0-альфа.1
тома:
- тип: связать
источник: ./кето
цель: /дом/ори
окружающая обстановка:
- LOG_LEVEL=отладка
- DSN=postgres://кето:секрет@постгрес-кето:5432/кето?sslmode=disable&max_conns=20&max_idle_conns=4
команда: ["мигрировать", "вверх", "-y"]
перезапуск: при сбое
зависит от:
- постгрес-кратос
сети:
- интранет
кето-завивка:
изображение: orid/кето:v0.7.0-альфа.1
тома:
- тип: связать
источник: ./кето
цель: /дом/ори
окружающая обстановка:
- KETO_WRITE_REMOTE=кето:4467
- KETO_READ_REMOTE=кето:4466
- LOG_LEVEL=отладка
- DSN=postgres://кето:секрет@постгрес-кето:5432/кето?sslmode=disable&max_conns=20&max_idle_conns=4
зависит от:
- постгрес-кратос
сети:
- интранет
кето:
изображение: orid/кето:v0.7.0-альфа.1
тома:
- тип: связать
источник: ./кето
цель: /дом/ори
порты:
- '4466:4466'
- '4467:4467'
зависит от:
- кето-мигрировать
окружающая обстановка:
- DSN=postgres://кето:секрет@постгрес-кето:5432/кето?sslmode=disable&max_conns=20&max_idle_conns=4
сети:
- интранет
команда: служить
тома:
узлы-модули:
кратос-sqlite:
сети:
интранет:
Работа с политиками
Keto настроил пространство имен app для использования в приложении Flask. Следуя руководству [Проверить, есть ли у пользователя доступ к чему-либо] (https://www.ory.sh/keto/docs/guides/simple-access-check-guide), я решил реализовать простую политику разрешений для демонстрационного проекта:
- Используйте кето-кли для управления разрешениями.
- Используйте электронную почту для subjects без символа
@
.
Плюсы
- Простота в использовании и обслуживании.
- Можно легко автоматизировать с помощью конвейеров CI/CD.
Минусы
- Отсутствие пользовательского интерфейса может стать препятствием для нетехнического персонала.
- Эта политика разрешений может нарушать GDPR, HIPAA или любые другие требования. в связи с использованием персональных данных.
Колба часть
```питон
HTTP_STATUS_FORBIDDEN = 403
@blueprint.route("/", методы=["GET", "POST"])
защита дома():
"""Домашняя страница."""
если ory_kratos_session отсутствует в request.cookies:
вернуть перенаправление (настройки.KRATOS_UI_URL)
ответ = запросы.получить(
f"{settings.KRATOS_EXTERNAL_API_URL}/sessions/whoami",
куки=request.cookies
активный = ответ.json (). Получить ('активный')
если не активно:
прервать (HTTP_STATUS_FORBIDDEN)
электронная почта = response.json().get('идентификация', {}).get('признаки', {}).get('электронная почта').replace('@', '')
Проверить разрешения
ответ = запросы.получить(
f"{settings.KETO_API_READ_URL}/проверить",
параметры = {
"пространство имен": "приложение",
"объект": "домашняя страница",
"отношение": "читать",
"subject_id": электронная почта,
если нет response.json().get("разрешено"):
прервать (HTTP_STATUS_FORBIDDEN)
вернуть render_template("public/home.html")
@blueprint.route("/присяга", методы=["GET", "POST"])
защита присяги():
""" Пример пути к демонстрационной интеграции Oathkeeper с Kratos """
вернуть {"сообщение": "привет"}
Примечание
- Рассмотрите возможность использования пакетов
авторизации
иаутентификации
, которые используют Kratos SDK и Keto SDK. Вместо того, чтобы просто вызывать некоторые волшебные конечные точки, ваш код будет более читабельным с помощью SDK.
- Пожалуйста, обратите внимание на настройку сессии входа и файлов cookie.
- Лучше использовать Ory Cloud вместо того, чтобы ваша команда управляла Ory Kratos только потому, что Ory управляет им, а вы нет. необходимо включить наблюдаемость/регистрацию/показатели для вашего сервиса.
Оригинал