【Microsoft ID プラットフォーム】(Azure AD) Python Web アプリ-設定編-

はじめに（背景)
----
下記検証の続きとなります。

SPA (Node.js)
https://qiita.com/Design_Tshirt7/items/553958e3724cc3718aa9
ASP.NET
https://qiita.com/Design_Tshirt7/items/c282d645c2117be12d4e
ASP.NET Core
https://qiita.com/Design_Tshirt7/items/ed8d45a0dff76b741c03
Java Web アプリ (WARfile)
https://qiita.com/Design_Tshirt7/items/df8dd7799bfdc32c9078
Java Web アプリ (eclipse)
https://qiita.com/Design_Tshirt7/items/f9c78f31ad47173577ab

背景は、上記と同じとなりますが、初めてご訪問頂いた人もいると思いますので、記載させて頂きます。

Office365を導入して、数年が経ちました。
皆様が慣れてきて、そろそろ、Office365とのシングルサインをすれば、便利になるんじゃない！！との声が出来てきました。そして、上司から、"Single Sign On よろしく！"との恐ろしい声がかかりました。

確かにIDaaSとしてのAzure ADは既に稼働しているので、後は、連携するアプリケーションの準備が出来れば可能ですが、、、このオンプレWebアプリケーションとIDaaSとのSSOは敷居が高い。

なぜなら、アプリケーション側でSAML/OpenIDConnect/OAuthとおしゃべりができないので、改修が必須となる。そこで、Microsoft ID プラットフォームを使えば、ライブラリが提供されているので、これをうまく活用すれば、SSOの敷居が少しでも低くるなると考え、検証を開始致しました。

Microsoft ID プラットフォーム
-----
『Microsoft ID プラットフォーム (旧称: 開発者向け Azure Active Directory)』
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/

Microsoft ID プラットフォームは、Azure Active Directory (Azure AD) 開発者プラットフォームの進化版です。 これにより、すべての Microsoft ID にサインインして、Microsoft API (Microsoft Graph) や開発者が構築した API を呼び出すためのトークンを取得するアプリケーションを開発者が構築できます。 これはフル機能を備えたプラットフォームであり、OAuth 2.0 および OpenID Connect 標準に準拠した認証サービス、オープンソース ライブラリ、アプリケーションの登録および構成、充実した概念とリファレンスのドキュメント、クイック スタート サンプル、コード サンプル、チュートリアル、攻略ガイドによって構成されています。

ふむふむ。確かにサンプルコードがあるので、できそうかも。。。

いざトライ！！
-----
1.参照ページ
『クイック スタート: Python Web アプリに Microsoft でサインインを追加する』
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/quickstart-v2-python-webapp

2.登場人物
1.Identity Provider (Azure AD)
* オンマイクロソフトアカウントを使います。
2.Relying Party (Python)
(事前の準備をお願い致します。インストール方法は割愛させて頂きます)
-Python 3.8
-Flask、Flask-Session、要求
-MSAL Python


3.手順
<b>◆手順1:アプリケーションの登録</b>
1.Azure portal(https://portal.azure.com) にサインインします。
2.[ホーム]-> [Azure AD Active Directory] -> [アプリの登録]へ進む
<img width="200" alt="1.appregi.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/508db363-c91f-0a29-3ad8-e7d68db2bbdb.png">

3.[新規登録] をクリックします。
<img width="400" alt=".appnew.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/f585f16b-b5b2-70fc-6763-bc1296df1f37.png">

4.アプリケーション登録で下記項目を選択して、[登録]をクリック。
(1).名前欄：任意のアプリケーション名を入力
(2).サポートされているアカントの種類：この組織ディレクトリのみに含まれるアカウント
(3).リダイレクトURL：空白　=> (後ほど、入力されます。)
<img width="400" alt="1.reg.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/c81048b0-ad05-e664-7430-f673d959295a.png">

5.登録したアプリケーションが表示されますので、[クイックスタート]をクリック。
<img width="400" alt="2.quickstart.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/0fbf9f1a-85f9-78fa-0ea2-16d919b9718e.png">

6.クイックスタートガイドの[Python]をクリック。
<img width="400" alt="3.Python.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/a776777a-39e8-b2dc-3c34-9b9450f4f169.png">

7.[この変更を行う]をクリック。
<img width="400" alt="4.change.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/3e2cc9bb-4605-0d98-c41d-bbbd78068007.png">

8.下記構成内容が表示されますので、[更新する]をクリック。
(1).リダイレクト URI : 
http://localhost:5000/getAToken
(2).委任されたアクセス許可：User.ReadBasic.All
(3).クライアントシークレット
* 認可コードフローとなりますので、アクセストーンとIDトークンのチェックは無しとなっております。
<img width="400" alt="5.update.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/85ca8e78-026b-b920-3238-8a92f5aaa674.png">

9.クライアントシークレットが表示されますので、コピーをして、[完了]をクリック。
* クライアントシークレットは以降の手順で必要となりますので、必ずコピーをお願い致します。
<img width="400" alt="6.secret.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/c0108706-f971-62df-4b91-6444dce794a7.png">

10.下記の[認証]画面から応答URLの内容が反映されている事を確認。
<img width="500" alt="7.Authn.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/40da69d4-4a60-85da-3168-052662df090b.png">

11.下記の[APIのアクセス許可]画面からアクセス許可の内容が反映されている事を確認。
<img width="500" alt="8.APIpermission.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/a3603aa3-a3c5-e0c1-e8f7-540618017a1d.png">

<b>◆手順2:プロジェクトのダウンロード</b>
1.コードサンプルファイルをダウンロードします。
コードサンプル：ms-identity-python-webapp-master.zip
<img width="399" alt="1.download.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/659e2120-02f9-3bbe-2891-ef139f0475b6.png">

<b>◆手順3:コード サンプルの構成</b>
1.ZIP ファイルをローカル フォルダーに展開します。
2.展開したフォルダのapp.config.pyを編集致します。
<img width="400" alt="1.foldername.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/e7917d62-b0aa-ebb1-53f8-2a5c1e944778.png">

|name|value|
|---|---|
|Enter_the_Application_Id_here|f7061e03-8637-4c41-82b4-8da8848fd2b4|
|Enter_the_Client_Secret_Here|qDSRE_XZ/w4Bdxr@Dg[0kloVAzzDKG49|
|Enter_the_Tenant_Name_Here|a94216cd-7c42-4b24-8ba0-ce5c210951bd|

<img width="500" alt="2.application.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/e7e02f5d-1c69-66e5-929d-0773aef5553f.png">

<b>◆手順4:Flask、Flask-Session、MSAL Pythonのインストール</b>
4-1.Flaskのインストール (pip install flask)

```
C:\Users\xxxx\AppData\Local\Programs\Python\Python38>pip install flask
Collecting flask
  Downloading https://files.pythonhosted.org/packages/9b/93/628509b8d5dc749656a9641f4caf13540e2cdec85276964ff8f43bbb1d3b/Flask-1.1.1-py2.py3-none-any.whl (94kB)
     |????????????????????????????????| 102kB 1.3MB/s
Collecting itsdangerous>=0.24 (from flask)
  Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting click>=5.1 (from flask)
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
     |????????????????????????????????| 81kB 1.8MB/s
Collecting Jinja2>=2.10.1 (from flask)
  Downloading https://files.pythonhosted.org/packages/27/24/4f35961e5c669e96f6559760042a55b9bcfcdb82b9bdb3c8753dbe042e35/Jinja2-2.11.1-py2.py3-none-any.whl (126kB)
     |????????????????????????????????| 133kB 3.3MB/s
Collecting Werkzeug>=0.15 (from flask)
  Downloading https://files.pythonhosted.org/packages/ba/a5/d6f8a6e71f15364d35678a4ec8a0186f980b3bd2545f40ad51dd26a87fb1/Werkzeug-1.0.0-py2.py3-none-any.whl (298kB)
     |????????????????????????????????| 307kB 3.3MB/s
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10.1->flask)
  Downloading https://files.pythonhosted.org/packages/4f/8b/da8a2ae5780d38271ac6e691756fc938cf4df8f225eb8aaced0204304932/MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl
Installing collected packages: itsdangerous, click, MarkupSafe, Jinja2, Werkzeug, flask
Successfully installed Jinja2-2.11.1 MarkupSafe-1.1.1 Werkzeug-1.0.0 click-7.0 flask-1.1.1 itsdangerous-1.1.0
```

4-2.Flask-Sessionのインストール (pip install Flask-Session)

```
C:\Users\xxxxx\AppData\Local\Programs\Python\Python38\flask>pip install Flask-Session
Collecting Flask-Session
  Downloading https://files.pythonhosted.org/packages/7e/a3/3ba4cec2becb7c4e65dfa95052c7050832c12a1fc8a475ac572842c460bc/Flask_Session-0.3.1-py2.py3-none-any.whl
Requirement already satisfied: Flask>=0.8 in c:\users\xxxxx\appdata\local\programs\python\python38\lib\site-packages (from Flask-Session) (1.1.1)
Requirement already satisfied: Werkzeug>=0.15 in c:\users\xxxxx\appdata\local\programs\python\python38\lib\site-packages (from Flask>=0.8->Flask-Session) (1.0.0)
Requirement already satisfied: click>=5.1 in c:\users\xxxxx\appdata\local\programs\python\python38\lib\site-packages (from Flask>=0.8->Flask-Session) (7.0)
Requirement already satisfied: itsdangerous>=0.24 in c:\users\xxxxx\appdata\local\programs\python\python38\lib\site-packages (from Flask>=0.8->Flask-Session) (1.1.0)
Requirement already satisfied: Jinja2>=2.10.1 in c:\users\xxxxx\appdata\local\programs\python\python38\lib\site-packages (from Flask>=0.8->Flask-Session) (2.11.1)
Requirement already satisfied: MarkupSafe>=0.23 in c:\users\xxxxx\appdata\local\programs\python\python38\lib\site-packages (from Jinja2>=2.10.1->Flask>=0.8->Flask-Session) (1.1.1)
Installing collected packages: Flask-Session
Successfully installed Flask-Session-0.3.1
```

4-3.MSAL Pythonのインストール (pip install msal)
●githubからpython用のmsal libraryをダウンロードして、下記フォルダに展開する。
https://github.com/AzureAD/microsoft-authentication-library-for-python
<img width="400" alt="2.msallibrary.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/3cd5cfd9-3eae-b9d1-cf68-c99b508a32e9.png">

●展開したフォルダにて、pip install msalを実行する。

```
C:\tmp\ms-identity-python-webapp-master\microsoft-authentication-library-for-python-dev>pip install msal
Collecting msal
  Downloading https://files.pythonhosted.org/packages/d6/de/11e9def2d98da8ddd1793db5e4b3c4398d923a561dad250bcf3cdce9be2b/msal-1.1.0-py2.py3-none-any.whl (44kB)
     |????????????????????????????????| 51kB 1.6MB/s
Collecting PyJWT[crypto]<2,>=1.0.0 (from msal)
  Downloading https://files.pythonhosted.org/packages/87/8b/6a9f14b5f781697e51259d81657e6048fd31a113229cf346880bb7545565/PyJWT-1.7.1-py2.py3-none-any.whl
Collecting requests<3,>=2.0.0 (from msal)
  Downloading https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl (57kB)
     |????????????????????????????????| 61kB 1.9MB/s
Collecting cryptography>=1.4; extra == "crypto" (from PyJWT[crypto]<2,>=1.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/27/da/8ee8775f0b6883b6c53e3f2d8a9a1e109661176446ec09f27c070dfc7baf/cryptography-2.8-cp38-cp38-win_amd64.whl (1.5MB)
     |????????????????????????????????| 1.5MB 3.3MB/s
Collecting idna<2.9,>=2.5 (from requests<3,>=2.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl (58kB)
     |????????????????????????????????| 61kB 3.8MB/s
Collecting chardet<3.1.0,>=3.0.2 (from requests<3,>=2.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
     |????????????????????????????????| 143kB 3.3MB/s
Collecting certifi>=2017.4.17 (from requests<3,>=2.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/b9/63/df50cac98ea0d5b006c55a399c3bf1db9da7b5a24de7890bc9cfd5dd9e99/certifi-2019.11.28-py2.py3-none-any.whl (156kB)
     |????????????????????????????????| 163kB 6.8MB/s
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests<3,>=2.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/e8/74/6e4f91745020f967d09332bb2b8b9b10090957334692eb88ea4afe91b77f/urllib3-1.25.8-py2.py3-none-any.whl (125kB)
     |????????????????????????????????| 133kB 6.8MB/s
Collecting six>=1.4.1 (from cryptography>=1.4; extra == "crypto"->PyJWT[crypto]<2,>=1.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/65/eb/1f97cb97bfc2390a276969c6fae16075da282f5058082d4cb10c6c5c1dba/six-1.14.0-py2.py3-none-any.whl
Collecting cffi!=1.11.3,>=1.8 (from cryptography>=1.4; extra == "crypto"->PyJWT[crypto]<2,>=1.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/b4/78/eefed9f51baa2b2c891915b4590a237ed6bc6d02beec177fc503bae8eb53/cffi-1.14.0-cp38-cp38-win_amd64.whl (177kB)
     |????????????????????????????????| 184kB 6.4MB/s
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography>=1.4; extra == "crypto"->PyJWT[crypto]<2,>=1.0.0->msal)
  Downloading https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz (158kB)
     |????????????????????????????????| 163kB 3.2MB/s
Installing collected packages: six, pycparser, cffi, cryptography, PyJWT, idna, chardet, certifi, urllib3, requests, msal
  Running setup.py install for pycparser ... done
Successfully installed PyJWT-1.7.1 certifi-2019.11.28 cffi-1.14.0 chardet-3.0.4 cryptography-2.8 idna-2.8 msal-1.1.0 pycparser-2.19 requests-2.22.0 six-1.14.0 urllib3-1.25.8
```

<b>◆手順5:コード サンプルの実行</b>
1.コードサンプルの実行を致します。(pip install -r requirements.txt)

```
C:\tmp\ms-identity-python-webapp-master>pip install -r requirements.txt
Requirement already satisfied: Flask<2,>=1 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from -r requirements.txt (line 1)) (1.1.1)
Requirement already satisfied: Flask-Session<1,>=0 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from -r requirements.txt (line 2)) (0.3.1)
Requirement already satisfied: requests<3,>=2 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from -r requirements.txt (line 3)) (2.22.0)
Requirement already satisfied: msal<2,>=0 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from -r requirements.txt (line 4)) (1.1.0)
Requirement already satisfied: Werkzeug>=0.15 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from Flask<2,>=1->-r requirements.txt (line 1)) (1.0.0)
Requirement already satisfied: click>=5.1 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from Flask<2,>=1->-r requirements.txt (line 1)) (7.0)
Requirement already satisfied: Jinja2>=2.10.1 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from Flask<2,>=1->-r requirements.txt (line 1)) (2.11.1)
Requirement already satisfied: itsdangerous>=0.24 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from Flask<2,>=1->-r requirements.txt (line 1)) (1.1.0)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2->-r requirements.txt (line 3)) (1.25.8)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2->-r requirements.txt (line 3)) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2->-r requirements.txt (line 3)) (2019.11.28)
Requirement already satisfied: idna<2.9,>=2.5 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from requests<3,>=2->-r requirements.txt (line 3)) (2.8)
Requirement already satisfied: PyJWT[crypto]<2,>=1.0.0 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from msal<2,>=0->-r requirements.txt (line 4)) (1.7.1)
Requirement already satisfied: MarkupSafe>=0.23 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from Jinja2>=2.10.1->Flask<2,>=1->-r requirements.txt (line 1)) (1.1.1)
Requirement already satisfied: cryptography>=1.4; extra == "crypto" in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from PyJWT[crypto]<2,>=1.0.0->msal<2,>=0->-r requirements.txt (line 4)) (2.8)
Requirement already satisfied: six>=1.4.1 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from cryptography>=1.4; extra == "crypto"->PyJWT[crypto]<2,>=1.0.0->msal<2,>=0->-r requirements.txt (line 4)) (1.14.0)
Requirement already satisfied: cffi!=1.11.3,>=1.8 in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from cryptography>=1.4; extra == "crypto"->PyJWT[crypto]<2,>=1.0.0->msal<2,>=0->-r requirements.txt (line 4)) (1.14.0)
Requirement already satisfied: pycparser in c:\users\xxxxxappdata\local\programs\python\python38\lib\site-packages (from cffi!=1.11.3,>=1.8->cryptography>=1.4; extra == "crypto"->PyJWT[crypto]<2,>=1.0.0->msal<2,>=0->-r requirements.txt (line 4)) (2.19)
```

<b>◆手順6: サインイン</b>
*事前準備
(1).Fiddlerでパケットキャプチャの準備。
(2).ダウンロードしたコアプロジェクトサンプルの仕組みをきちんと確認。
<img width="500" alt="Flow.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/5293e79a-7580-1fc6-c901-f234078ad062.png">

0.コマンド ラインから app.py を実行するが、[ModuleNotFoundError: No module named 'werkzeug.contrib]エラーで実行できかったので、[pip install werkzeug==0.16.0]を実行致しました。

```
C:\tmp\ms-identity-python-webapp-master>python app.py
Traceback (most recent call last):
  File "app.py", line 11, in <module>
    Session(app)
  File "C:\Users\jpr00168\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_session\__init__.py", line 54, in __init__
    self.init_app(app)
  File "C:\Users\jpr00168\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_session\__init__.py", line 61, in init_app
    app.session_interface = self._get_interface(app)
  File "C:\Users\jpr00168\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_session\__init__.py", line 90, in _get_interface
    session_interface = FileSystemSessionInterface(
  File "C:\Users\jpr00168\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_session\sessions.py", line 313, in __init__
    from werkzeug.contrib.cache import FileSystemCache
ModuleNotFoundError: No module named 'werkzeug.contrib'
```

```
C:\tmp\ms-identity-python-webapp-master>pip install werkzeug==0.16.0
Collecting werkzeug==0.16.0
  Downloading Werkzeug-0.16.0-py2.py3-none-any.whl (327 kB)
     |????????????????????????????????| 327 kB 731 kB/s
Installing collected packages: werkzeug
  Attempting uninstall: werkzeug
    Found existing installation: Werkzeug 1.0.0
    Uninstalling Werkzeug-1.0.0:
      Successfully uninstalled Werkzeug-1.0.0
Successfully installed werkzeug-0.16.0
```

1.気をとりなして、[python app.py]の実行

```
C:\tmp\ms-identity-python-webapp-master>python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

2.認可コードの取得（認可エンドポイント)
2-1.http://localhost:5000 にアクセスして、[Sign In]をクリック。
<img width="380" alt="1.login.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/353c7602-daea-cc93-ad4e-d5ce73298350.png">

2-2.資格情報(ID/パスワード)の入力。
2-3.要求されているアクセス許可を承諾。
<img width="303" alt="2.consent1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/bcf6ddf5-b741-3939-8ce0-4063ded7c5a6.png">

2-4.ログインが完了して、アカント情報(test3)が表示されます。
<img width="383" alt="3.login2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/d5581553-804f-b047-b015-8823ef0607a5.png">

3.User Infoエンドポイントへのアクセス
3-1.[Call Microsoft Graph API]をクリック。
<img width="383" alt="3-2.login2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/9ba96d3f-40df-b5c3-fe14-aa8329b87fc1.png">
3-2.テナントのユーザー情報が表示されます。
<img width="560" alt="4.grah.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/f77f106d-aabb-0117-5509-aadb2006e7a1.png">
3-3.コンソールログは、下記となります。

```
C:\tmp\ms-identity-python-webapp-master>python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [20/Feb/2020 15:54:47] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [20/Feb/2020 15:54:47] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:54:54] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [20/Feb/2020 15:54:55] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:54:57] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [20/Feb/2020 15:55:33] "GET /getAToken?error=consent_required&error_description=AADSTS65004%3a+User+declined+to+consent+to+access+the+app.%0d%0aTrace+ID%3a+54221221-e5bc-4f5c-af4f-6f6afb746201%0d%0aCorrelation+ID%3a+c3c77167-c160-4d2c-a6b4-546bc9a9e155%0d%0aTimestamp%3a+2020-02-20+06%3a55%3a32Z&error_uri=https%3a%2f%2flogin.microsoftonline.com%2ferror%3fcode%3d65004&state=783dda9a-df84-480b-a120-90fa96cb98c0 HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:55:59] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [20/Feb/2020 15:56:00] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:56:14] "GET /getAToken?error=consent_required&error_description=AADSTS65004%3a+User+declined+to+consent+to+access+the+app.%0d%0aTrace+ID%3a+bed29f82-2167-4080-ad46-454c8f119301%0d%0aCorrelation+ID%3a+5883bde6-96dd-44fb-ba39-8104b134eb79%0d%0aTimestamp%3a+2020-02-20+06%3a56%3a13Z&error_uri=https%3a%2f%2flogin.microsoftonline.com%2ferror%3fcode%3d65004&state=ccb20b98-be76-42fa-aa25-5b624ef0fa19 HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:57:34] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [20/Feb/2020 15:57:36] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:58:23] "GET /getAToken?code=OAQABAAIAAABeAFzDwllzTYGDLh_qYbH8gPU4ERUg5W6vRzIgLsFHA1eUarRW7TUp99wUDxmQ2y5YqBRNEBg04YxwzAejKo3UocHgDVXZc8sY1FKJEz9PljMO7ElXHBiPhxogOb1FyoWPKLrGk8w3imfCHG70COwT3J5mjkVT0UXPdIFsDuRgo3DH8G3kjnPKkJMkRp4YJYiVl6Ear3hD2ua_HbXsiklhUsYfibaKjUGBce-eZiByNjftiKvVOWZlcN0XY947sMkIQqu63e4J-NBn_Pg_1yoGqZjlMJPiHJyyZD8Yon_bVUD83TbtcGSlFBMpW-mnDN_evbpRV3QY8RbzNXfkyNDIdMPVoaCozp70GkyHe8TLusZA8C6Km0hs0dm-0DCScQc7092xFZUQ3rliw8E97HbHF3Melx9PW5Egd_faes4x_C1r79jHy__-lIvJHog5jJeOSj9onn-heX7xvnTr4tBmZgPqip59Rh0rCqPWCbFD89_rNWnjZZEjh3KTGwEkLwSZf9UZ1WLD72uA9N5BAyzeIiPTECXwfNhu7pGc8V2LMxLx3K4G3haczpzxy83Ij6lfVtcdqIndV-IUnkAbgtKtx0UZNRTGCXPW6YOJSmOfwPrUk_EdzruljK9-LW0bkId9CQk1yXAUp6pLqR4oanuYIx2mYoBDFH8VcB9kIWq639vKzkQ91imQQOplV-4ysccsmy2r-EOJjNn7onhw588BjP6TjC2fWNnjjQOt0trseMfwV5y6cZmwhPlO1NIZKB6yFH42Kyum2g5Q6_Ke5gXEIAA&state=2e1d18fc-82a7-42a6-8169-50a99d47065e&session_state=17b19f7c-c851-4e01-87a2-ec5f0f711b87 HTTP/1.1" 302 -
127.0.0.1 - - [20/Feb/2020 15:58:24] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [20/Feb/2020 15:58:48] "GET /graphcall HTTP/1.1" 200 -
```

無事ログイン完了!!

まとめ
-----
一通り、クイックスタートの検証は、完了致しました。
次回は、認可コードフローについて、情報を投稿したいと思います。

まだまだAzure B2Cの検証結果, SaaS SSO検証等の投稿したい記事は、たくさんあるのですが、時間が足りないです。。。

最後に、私の記事が少しでも、皆様の役に立てれば幸いでございます。