次の方法で共有


チュートリアル: Microsoft ID プラットフォームを使用して Python Flask Web アプリにユーザーをサインインさせる

適用対象: 白いチェック マーク記号が付いた緑の円。 従業員テナント 白いチェック マーク記号が付いた緑の円。 外部テナント (詳細はこちら)

このチュートリアルでは、Python Flask Web アプリのセキュリティ保護について説明します。

このチュートリアルでは、次の操作を行います。

  • Python Flask プロジェクトを作成する
  • 必要な依存関係をインストールする
  • 認証に Microsoft ID プラットフォームを使用するように Flask Web アプリを構成する
  • Flask Web アプリでサインインとサインアウトのエクスペリエンスをテストする

[前提条件]

Flask プロジェクトを作成する

  1. Flask-web-app など、Flask アプリケーションをホストするフォルダーを作成します。

  2. コンソール ウィンドウを開き、コマンドを使用して Flask Web アプリ フォルダーのディレクトリに移動します

    cd flask-web-app
    
  3. 仮想環境を設定する

    オペレーティング システムに応じて、次のコマンドを実行して仮想環境を設定し、アクティブ化します。

    Windows オペレーティング システムの場合:

    py -m venv .venv
    .venv\scripts\activate
    

    macOS または Linux オペレーティング システムの場合:

    python3 -m venv .venv
    source .venv/bin/activate
    

アプリの依存関係をインストールする

アプリの依存関係をインストールするには、次のコマンドを実行します。

pip install flask
pip install python-dotenv
pip install requests
pip install "ms_identity_python[flask] @ git+https://github.com/azure-samples/ms-identity-python@0.9"

インストールする ms_identity_python ライブラリでは、依存関係として Python 用 Microsoft Authentication Library (MSAL) が自動的にインストールされます。 MSAL Python は、ユーザーの認証とアクセス トークンの管理を可能にするライブラリです。

必要なライブラリをインストールしたら、次のコマンドを実行して要件ファイルを更新します。

pip freeze > requirements.txt

構成を追加する

  1. ルート フォルダーに .env* ファイルを作成して、アプリの構成を安全に格納します。 .env ファイルには、次の環境変数が含まれている必要があります。

    CLIENT_ID="<Enter_your_client_id>"
    CLIENT_SECRET="<Enter_your_client_secret>"
    AUTHORITY="https://login.microsoftonline.com/<Enter_tenant_id>"
    REDIRECT_URI="<Enter_redirect_uri>"
    

    プレースホルダーを次の値に置き換えます。

    • <Enter_your_client_id>を、登録したクライアント Web アプリのアプリケーション (クライアント) ID に置き換えます。
    • <Enter_tenant_id>を、Web アプリを登録したディレクトリ (テナント) ID に置き換えます。
    • <Enter_your_client_secret>を、作成した Web アプリのクライアント シークレット値に置き換えます。 このチュートリアルでは、デモンストレーションのためにシークレットを使用します。 運用環境では、 証明書やフェデレーション ID 資格情報などのより安全な方法を使用します。
    • <Enter_redirect_uri>を、先ほど登録したリダイレクト URI に置き換えます。 このチュートリアルでは、リダイレクト URI パスを http://localhost:3000/getAToken に設定します。
  2. 環境変数を読み取り、必要な他の構成を追加する app_config.py ファイルを作成します。

    import os
    
    AUTHORITY = os.getenv("AUTHORITY")
    CLIENT_ID = os.getenv("CLIENT_ID")
    CLIENT_SECRET = os.getenv("CLIENT_SECRET")
    REDIRECT_URI = os.getenv("REDIRECT_URI")
    SESSION_TYPE = "filesystem" # Tells the Flask-session extension to store sessions in the filesystem. Don't use in production apps.
    

アプリ エンドポイントを構成する

この段階では、Web アプリ エンドポイントを作成し、ビジネス ロジックをアプリケーションに追加します。

  1. ルート フォルダーに app.py という名前のファイルを作成します。

  2. 必要な依存関係を app.py ファイルの先頭にインポートします。

    import os
    import requests
    from flask import Flask, render_template
    from identity.flask import Auth
    import app_config
    
  3. Flask アプリを初期化し、 app_config.py ファイルで指定したセッション ストレージの種類を使用するように構成します。

    app = Flask(__name__)
    app.config.from_object(app_config)
    
  4. アプリ クライアントを初期化します。 Flask Web アプリは機密クライアントです。 クライアントシークレットを、機密クライアントが安全に保存できるため、提供します。 内部では、ID ライブラリは MSAL ライブラリの ConfidentialClientApplication クラスを呼び出します。

    auth = Auth(
        app,
        authority=app.config["AUTHORITY"],
        client_id=app.config["CLIENT_ID"],
        client_credential=app.config["CLIENT_SECRET"],
        redirect_uri=app.config["REDIRECT_URI"]
    )
    
  5. 必要なエンドポイントを Flask アプリに追加します。 Web アプリは、承認コード フローを使用してユーザーをサインインします。 ms_identity_python MSAL ラッパー ライブラリは、MSAL ライブラリとの対話に役立ちます。そのため、サインインを追加してアプリにサインアウトすることが容易になります。 インデックス ページを追加し、login_required提供される デコレーターを使用して保護します。 login_required デコレーターにより、認証されたユーザーのみがインデックス ページにアクセスできるようになります。

    @app.route("/")
    @auth.login_required
    def index(*, context):
        return render_template(
            'index.html',
            user=context['user'],
            title="Flask Web App Sample",
        )
    

    このビューを @login_requiredで装飾したため、ユーザーが存在することが保証されます。

アプリ テンプレートを作成する

ルート フォルダーにテンプレートという名前 フォルダーを作成します。 templates フォルダーに、 index.htmlという名前のファイルを作成します。 これはアプリのホームページです。 index.html ファイルに次のコードを追加します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ title }}</h1>
    <h2>Welcome {{ user.get("name") }}!</h2>

    <img src="https://github.com/Azure-Samples/ms-identity-python-webapp-django/raw/main/static/topology.png" alt="Topology">

    <ul>
    {% if api_endpoint %}
        <!-- If an API endpoint is declared and scopes defined, this link will show. We set this in the call an API tutorial. For this tutorial, we do not define this endpoint. -->
        <li><a href='/call_api'>Call an API</a></li>
    {% endif %}

    <li><a href="{{ url_for('identity.logout') }}">Logout</a></li>
    </ul>

    <hr>
    <footer style="text-align: right">{{ title }}</footer>
</body>
</html>

サンプル Web アプリを実行してテストする

  1. ご利用のターミナルで、次のコマンドを実行します。

    python3 -m flask run --debug --host=localhost --port=3000
    

    選択したポートを使用できます。 このポートは、先ほど登録したリダイレクト URI のポートに似ている必要があります。

  2. ブラウザーを開き、 http://localhost:3000に移動します。 サインイン ページが表示されます。

  3. 手順に従って、Microsoft アカウントでサインインします。 サインインするための電子メール アドレスとパスワードを指定するように求められます。

  4. アプリケーションで必要なスコープがある場合は、同意画面が表示されます。 アプリケーションは、アクセスを許可するデータへのアクセスを維持し、サインインするためのアクセス許可を要求します。 を選択し、を同意します。 スコープが定義されていない場合、この画面は表示されません。

サインインまたはサインアップすると、Web アプリにリダイレクトされます。 次のスクリーンショットのようなページが表示されます。

認証が成功した後の Flask Web アプリサンプルのスクリーンショット。

[ ログアウト ] を選択してアプリからサインアウトします。 サインアウトするアカウントを選択するように求められます。 サインインに使用したアカウントを選択します。

カスタム URL ドメインを使用する (省略可能)

ワークフォース テナントは、カスタム URL ドメインをサポートしていません。