Как защитить приложение Flask с помощью Ory Kratos и Ory Keto

Как защитить приложение Flask с помощью Ory Kratos и Ory Keto

16 марта 2022 г.

В настоящее время инженерное сообщество имеет множество продуктов для аутентификации в своих рамках. Многие из них имеют встроенные функции для аутентификации и множество библиотек, доступных для входа через социальные сети. У нас есть фреймворк Django, Flask и python-social-auth для создания почти всего, что нам нужно для аутентификации пользователей в мире python.


В этой статье я покажу вам пример того, как добавить все необходимое для аутентификации пользователя без написания большого количества строк кода. Код, используемый в этом сообщении в блоге, доступен на GitHub. Мы будем использовать Flaskflask cookie-cutter, dockerdocker-composePostgresОри Кратос и Ори Кето.


Давайте посмотрим на процесс входа в наше приложение с помощью Ory Kratos и Ory Keto.


[ Схема использования Ory Kratos и Keto для защиты приложения Flask] (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.

Минусы


  • Отсутствие пользовательского интерфейса может стать препятствием для нетехнического персонала.

  • Эта политика разрешений может нарушать GDPRHIPAA или любые другие требования. в связи с использованием персональных данных.

Колба часть


```питон


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.


  • Лучше использовать Ory Cloud вместо того, чтобы ваша команда управляла Ory Kratos только потому, что Ory управляет им, а вы нет. необходимо включить наблюдаемость/регистрацию/показатели для вашего сервиса.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE