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

Как добавить аутентификацию пользователя в приложения Flask с помощью Okta

Как быстро добавить аутентификацию пользователя в веб-приложения Flask с помощью сервиса Okta.

Автор оригинала: Matt Makai.

Аутентификация пользователя – основная функция в веб-приложения, чтобы люди могли создавать и получать доступ свои собственные аккаунты. К сожалению, аутентификацию не всегда легко настроить и есть много способов неправильно реализовать вход и выход из системы функции.

В этом руководстве рассказывается, как использовать безопасная служба аутентификации личности называется Okta , который предоставляется бесплатно до 1000 активные учетные записи пользователей, чтобы легко обрабатывать пользовательские данные во Flask Приложения.

Наши инструменты

Python 3 настоятельно рекомендуется для создания приложений, и это учебник был построен с помощью Python 3.7, хотя более ранние версии Python 3 тоже должно работать нормально. В дополнение к Python 3.x мы также будем использовать:

Весь код в этом сообщении в блоге предоставляется с открытым исходным кодом под Лицензия MIT на GitHub под каталог flask-auth-okta блога-кода-примеров репозиторий. Используйте и злоупотребляйте исходным кодом для приложений, которые вы хотите построить.

Установка зависимостей

Создайте новый Python virtualenv для этого проекта:

python3 -m venv flaskauth

Активируйте виртуальную среду с помощью скрипта activate :

. ./flaskauth/bin/activate

Командная строка должна измениться после активации:

Активация виртуального flaskauth.

Помните, что вам нужно будет активировать virtualenv в каждом терминале окно, в котором вы хотите использовать зависимости, содержащиеся в этом virtualenv.

Теперь мы можем установить Flask и зависимости Okta.

pip install flask>=1.0.2 flask-oidc>=1.4.0 okta==0.0.4

Найдите вывод, аналогичный приведенному ниже, чтобы убедиться, что зависимости Успешно установлен:

...
Collecting idna<2.8,>=2.5 (from requests>=2.5.3->okta)
  Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
    100% |████████████████████████████████| 61kB 16.6MB/s 
Collecting urllib3<1.24,>=1.21.1 (from requests>=2.5.3->okta)
  Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB)
    100% |████████████████████████████████| 143kB 14.0MB/s 
Installing collected packages: MarkupSafe, Jinja2, click, itsdangerous, Werkzeug, flask, pyasn1, pyasn1-modules, rsa, httplib2, six, oauth2client, flask-oidc, chardet, certifi, idna, urllib3, requests, python-dateutil, okta
  Running setup.py install for MarkupSafe ... done
  Running setup.py install for itsdangerous ... done
  Running setup.py install for httplib2 ... done
  Running setup.py install for flask-oidc ... done
  Running setup.py install for okta ... done
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 certifi-2018.8.24 chardet-3.0.4 click-6.7 flask-1.0.2 flask-oidc-1.4.0 httplib2-0.11.3 idna-2.7 itsdangerous-0.24 oauth2client-4.1.3 okta-0.0.4 pyasn1-0.4.4 pyasn1-modules-0.2.2 python-dateutil-2.7.3 requests-2.19.1 rsa-4.0 six-1.11.0 urllib3-1.23

Мы установили необходимые нам Flask и зависимости Okta, так что приступим к созданию приложение Flask.

Создание базового приложения Flask

Первый шаг перед добавлением аутентификации в наше приложение Flask – написать некоторые функции строительных лесов. Аутентификация подключится к эти функции, такие как вход и выход , для обеспечения аутентификации процесс работает правильно.

Создайте каталог для своего проекта с именем thundercats . Почему thundercats ? Почему не Thundercats?

В thundercats непосредственно создайте файл с именем app.py с следующее исходное содержание:

# imports for Flask
from flask import Flask, Response


app = Flask(__name__)


@app.route("/lair")
def lair():
    return Response("Thundercats (supposed to be hidden) lair.")


@app.route("/")
def landing_page():
    return Response("Thundercats, Thundercats, hoooooooooooo!")

Мы можем запустить наше приложение Flask, используя следующую команду:

set FLASK_APP=app.py
flask run

Перейдите на localhost: 5000 в своем веб-браузере, и вы должны увидеть:

Простая версия запущенного приложения Flask.

Теперь идем в наше «скрытое логово» по адресу localhost: 5000/lair/. В конце концов это страница должна требовать аутентификации для доступа, но пока она отображается без каких-либо проблем со входом:

Часть приложения Flask, которая должна быть скрыта за страницей входа.

Отлично, наше базовое приложение запущено, давайте перейдем к аутентификации. функциональность.

Auth-as-a-Service

Перейдите на страницу регистрации разработчиков Okta .

Целевая страница разработчиков Okta для регистрации.

Зарегистрируйте новую учетную запись или войдите в существующую.

Процесс регистрации разработчиков Okta.

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

Электронная почта подписки на Okta.

Нажмите кнопку «Войти» и войдите в учетную запись разработчика, используя временный пароль, указанный в электронном письме. Установите новый пароль и вызовите вопрос. Затем выберите изображение, соответствующее процессу входа в вашу учетную запись.

Okta завершить создание учетной записи.

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

Панель разработчика Okta.

Найдите «URL-адрес организации», как показано на следующем рисунке.

Значение URL-адреса Okta Org.

Мы собираемся использовать этот URL в нашем секретном файле учетных данных, чтобы наше веб-приложение Flask может правильно подключаться к службе Okta.

Создайте новый файл в каталоге вашего проекта с именем openidconnect_secrets.json со следующим содержимым:

{
  "web": {
    "client_id": "{{ OKTA_CLIENT_ID }}",
    "client_secret": "{{ OKTA_CLIENT_SECRET }}",
    "auth_uri": "{{ OKTA_ORG_URL }}/oauth2/default/v1/authorize",
    "token_uri": "{{ OKTA_ORG_URL }}/oauth2/default/v1/token",
    "issuer": "{{ OKTA_ORG_URL }}/oauth2/default",
    "userinfo_uri": "{{ OKTA_ORG_URL }}/oauth2/default/userinfo",
    "redirect_uris": [
      "http://localhost:5000/oidc/callback"
    ]
  }
}

Замените четыре заполнителя {{OKTA_ORG_URL}} значением URL организации. найдено в вашей панели управления. Мы заполним остальные заполнители с помощью фактические значения по мере прохождения обучения. Мой Файл openidconnect_secret.json в настоящее время будет иметь следующие значения основаны на моем URL-адресе организации панели разработчика. Помните, что значения ваших URL будут другими!

{
  "web": {
    "client_id": "{{ OKTA_CLIENT_ID }}",
    "client_secret": "{{ OKTA_CLIENT_SECRET }}",
    "auth_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/authorize",
    "token_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/token",
    "issuer": "https://dev-860408.oktapreview.com/oauth2/default",
    "userinfo_uri": "https://dev-860408.oktapreview.com/oauth2/default/userinfo",
    "redirect_uris": [
      "http://localhost:5000/oidc/callback"
    ]
  }
}

Хорошо, у нас настроена учетная запись Okta, поэтому мы можем добавить код аутентификации для нашего приложения Flask.

Подключение Flask к Okta

Нам нужно подключить наш код Flask к нашей новой учетной записи Okta. В рекомендуемый способ включения переменных, таких как учетные данные в приложении Flask проходит через обработка конфигурации поэтому мы будем использовать это в нашей учетной записи.

Обновите код Flask, указав следующие выделенные строки.

# imports for both Flask and Okta connection
from os import environ
from flask import Flask, Response
from flask_oidc import OpenIDConnect
from okta import UsersClient


app = Flask(__name__)
# secret credentials for Okta connection
app.config["OIDC_CLIENT_SECRETS"] = "openidconnect_secrets.json"
app.config["OIDC_COOKIE_SECURE"] = False
app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback"
app.config["OIDC_SCOPES"] = ["openid", "email", "profile"]
app.config["SECRET_KEY"] = environ.get("SECRET_KEY")
app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token"
# instantiate OpenID client to handle user session
oidc = OpenIDConnect(app)
# Okta client will determine if a user has an appropriate account
okta_client = UsersClient(environ.get("OKTA_ORG_URL"),
                          environ.get("OKTA_AUTH_TOKEN"))


@app.route("/lair")
def lair():
    return Response("Thundercats (supposed to be hidden) lair.")


@app.route("/")
def landing_page():
    return Response("Thundercats, Thundercats, hoooooooooooo!")

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

Остальной новый код задает конфигурацию приложения Flask. значения, которые можно использовать для создания экземпляров OpenID Connect и Клиенты Okta.

  • OIDC_CLIENT_SECRETS : расположение файла секретов OpenID Connect.
  • OIDC_COOKIE_SECURE : разрешает режим разработки для тестирования входа пользователя и
  • регистрация без SSL. Ваше приложение должно установить для него значение True в
  • производственное приложение.
  • OIDC_CALLBACK_ROUTE : URL-адрес в веб-приложении для обработки логинов пользователей.
  • OIDC_SCOPES : какие данные запрашивать о пользователе при входе в систему. Наши
  • приложение запрашивает основную информацию об электронной почте, имени и профиле
  • SECRET_KEY : это параметр Flask для обеспечения безопасности сеансов. Ключ
  • никогда не должны публиковаться, иначе пользовательские сеансы вашего веб-приложения будут
  • скомпрометирован.

Но где мы можем взять эти значения конфигурации приложения? Мы необходимо получить их из нашей учетной записи Okta, так что вернитесь на панель инструментов для создания нового приложения OpenID Connect.

Выберите приложения на панели инструментов разработчика Okta.

Приложения OpenID Connect используют идентификатор клиента и секрет клиента в место традиционных логинов и паролей. Идентификатор клиента и секрет клиента скажет вашему серверу авторизации распознать ваш применение. Нажмите кнопку «Добавить приложение».

Нажмите кнопку «Добавить приложение».

На экране нового приложения выберите «Интернет» и нажмите «Далее».

Выберите веб-приложение.

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

Установить значения конфигурации приложения.

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

На следующей странице прокрутите вниз, чтобы найти своего клиента и секретные ключи.

Сохраните учетные данные клиента для дальнейшего использования.

Скопируйте и вставьте идентификатор клиента и секрет клиента в следующий выделенные строки для замены {{OKTA_CLIENT_ID}} и {{OKTA_CLIENT_SECRET}} заполнители.

{
  "web": {
    "client_id": "{{ OKTA_CLIENT_ID }}",
    "client_secret": "{{ OKTA_CLIENT_SECRET }}",
    "auth_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/authorize",
    "token_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/token",
    "issuer": "https://dev-860408.oktapreview.com/oauth2/default",
    "userinfo_uri": "https://dev-860408.oktapreview.com/oauth2/default/userinfo",
    "redirect_uris": [
      "http://localhost:5000/oidc/callback"
    ]
  }
}

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

Перед обновлением у нас есть еще один шаг на панели инструментов разработчика Okta наше приложение Flask с кодом аутентификации: создание токен аутентификации API . Перейдите на вкладку API.

Щелкните вкладку API на панели управления.

Нажмите кнопку «Создать токен».

Создайте токен аутентификации для доступа к Okta.

Назовите токен ThunderFlaskCatsToken и скопируйте его. Сохраните токен где-нибудь безопасно, поскольку мы больше не сможем получить к нему доступ через панель управления. Мы собираются использовать этот токен при настройке среды OKTA_AUTH_TOKEN переменная в следующем разделе этого руководства.

Хорошо, наконец-то у нас есть вся конфигурация сервиса Okta и токены в наш файл openidconnect_secret.json , который нам нужен для завершения нашего приложения.

Защита логова

Наша конфигурация настроена, поэтому обновите файл app.py следующим образом: выделенные строки:

# imports for both Flask and Okta connection
from os import environ
from flask import Flask, Response, redirect, g, url_for
from flask_oidc import OpenIDConnect
from okta import UsersClient


app = Flask(__name__)
# secret credentials for Okta connection
app.config["OIDC_CLIENT_SECRETS"] = "openidconnect_secrets.json"
app.config["OIDC_COOKIE_SECURE"] = False
app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback"
app.config["OIDC_SCOPES"] = ["openid", "email", "profile"]
app.config["SECRET_KEY"] = environ.get("SECRET_KEY")
app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token"
# instantiate OpenID client to handle user session
oidc = OpenIDConnect(app)
# Okta client will determine if a user has an appropriate account
okta_client = UsersClient(environ.get("OKTA_ORG_URL"),
                          environ.get("OKTA_AUTH_TOKEN"))


@app.before_request
def before_request():
    if oidc.user_loggedin:
        g.user = okta_client.get_user(oidc.user_getfield("sub"))
    else:
        g.user = None


@app.route("/lair")
@oidc.require_login
def lair():
    return Response("Thundercats (supposed to be hidden) lair.")


@app.route("/")
def landing_page():
    return Response("Thundercats, Thundercats, hoooooooooooo!")


@app.route("/login")
@oidc.require_login
def login():
    return redirect(url_for(".lair"))


@app.route("/logout")
def logout():
    oidc.logout()
    return redirect(url_for(".landing_page"))

Вышеупомянутые новые выделенные строки проверяют, вошел ли пользователь в систему. перед каждым запросом. Если для маршрута требуется авторизованный пользователь из-за декоратор @ oidc.require_login , тогда пользователь будет перенаправлен на войдите на страницу. Мы также добавили маршруты в разделах /login и /logout , чтобы можно войти и выйти из приложения.

Задайте три переменные среды, чтобы наше приложение могло использовать их, когда мы запустить его. Убедитесь, что заполнители ORG_URL и AUTH_TOKEN установлены с ваше фактическое значение URL-адреса организации и токен аутентификации на панели инструментов разработчика Okta.

В командной строке выполните следующие команды, не забудьте заменить любые значения-заполнители с вашими собственными токенами и URL-адресами:

# this tells Flask we want to run the built-in server in dev mode
export FLASK_ENV=development
# make sure to use a very long random string here that cannot be guessed
export SECRET_KEY='a very long string with lots of numbers and letters'
# this is the same Org URL found on your developer dashboard
# for example, https://dev-860408.oktapreview.com
export OKTA_ORG_URL='ORG_URL'
# this is the API authentication token we created
export OKTA_AUTH_TOKEN='AUTH_TOKEN'

Теперь перезапустите приложение Flask:

set FLASK_APP=app.py
flask run

Вы должны быть в хорошей форме, если сервер разработки запускается с выводом как это:

(flaskauth)$ flask run
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 415-920-546

Направляйтесь на localhost: 5000 в браузере, в который вы еще не вошли. ваша учетная запись Okta (отлично работает окно в режиме инкогнито вашего веб-браузера).

Целевая страница в режиме инкогнито.

Давайте протестируем функцию перенаправления, когда мы попытаемся перейти в /lair маршрут, перейдя на localhost: 5000/lair. Мы перенаправляемся на Okta страница авторизации.

Перенаправление в режиме инкогнито.

Введите имя пользователя и пароль разработчика Okta, чтобы войти в приложение. Для целей разработки это подойдет для тестирования, но, очевидно, в производственное приложение, вы создадите другие учетные записи для входа пользователей.

Получил URL-адрес логова после входа в систему.

Давайте настроим еще один бит в нашем приложении, чтобы исправить явное отсутствие радость от успешного завершения кода аутентификации для этого руководство. Обновите две выделенные строки, чтобы они соответствовали тому, что находится в коде блок ниже:

# imports for both Flask and Okta connection
from os import environ
from flask import Flask, Response, redirect, g, url_for
from flask_oidc import OpenIDConnect
from okta import UsersClient


app = Flask(__name__)
# secret credentials for Okta connection
app.config["OIDC_CLIENT_SECRETS"] = "openidconnect_secrets.json"
app.config["OIDC_COOKIE_SECURE"] = False
app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback"
app.config["OIDC_SCOPES"] = ["openid", "email", "profile"]
app.config["SECRET_KEY"] = environ.get("SECRET_KEY")
app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token"
# instantiate OpenID client to handle user session
oidc = OpenIDConnect(app)
# Okta client will determine if a user has an appropriate account
okta_client = UsersClient(environ.get("OKTA_ORG_URL"),
                          environ.get("OKTA_AUTH_TOKEN"))


@app.before_request
def before_request():
    if oidc.user_loggedin:
        g.user = okta_client.get_user(oidc.user_getfield("sub"))
    else:
        g.user = None


@app.route("/lair")
@oidc.require_login
def lair():
    thundercats_lair = 'Thundercats, hoooo!

Thundercats now hidden lair.

via GIPHY

' return Response(thundercats_lair) @app.route("/") def landing_page(): return Response("Thundercats, Thundercats, hoooooooooooo!") @app.route("/login") @oidc.require_login def login(): """Force user to login and then redirect them to the lair. """ return redirect(url_for(".lair")) @app.route("/logout") def logout(): oidc.logout() return redirect(url_for(".landing_page"))

Обновите страницу логова.

Страница логова с новым GIF.

Хорошо, только немного лучше! Перейдите на localhost: 5000/выйдите из системы отменить аутентификацию вашего пользователя. Когда вы снова идете на localhost: 5000/lair, вы теперь придется повторно пройти аутентификацию.

Что теперь?

Мы только что создали пример приложения Flask с аутентификацией пользователя через Okta API .

Затем попробуйте следующие руководства, чтобы добавить другие функции в свой Приложение Flask:

  • Ответ на текстовые SMS-сообщения с помощью Python и Flask
  • Как добавить размещенный мониторинг в веб-приложения Flask
  • Разработка и запуск приложений Flask в контейнерах Docker

Вы также можете определить, что кодировать дальше в своем проекте Python, прочитав страница содержания Full Stack Python.

Вопросов? Свяжитесь со мной через Twitter @fullstackpython или @mattmakai . Я также на GitHub с имя пользователя mattmakai .

Что-то не так с этим сообщением? Вилка источник этой страницы на GitHub и отправьте запрос на перенос.