【Microsoft ID プラットフォーム】 (Azure AD) Postmanを使って認可コードフローを確認する

はじめに
------
一通り、クイックスタートによる検証が終わりましたので、最後に残っていた認証コードフローを確認していきたいと思います。

●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
●Python Web アプリ
https://qiita.com/Design_Tshirt7/items/4cc31d667a43641b92dd


Postmanと認可コードフロー
------
『Microsoft ID プラットフォームと OAuth 2.0 認証コード フロー』
https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow

上記URLに沿って、pythonでの認証コードフローを確認したいと思います。
確認を進めて行くと『アクセス トークンを要求する』のヒントで"Run in Postman"が登場致します。郵便屋さん？と思いきや、Web API開発で利用されるツールとなります。

<img width="600" alt="00.postman.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/d914c62f-1dc8-ff35-997f-abb8c2425090.png">

アクセストークン取得で必要となりますので、Postmanのインストールから初めて行きましょう！

いざスタート
-----

***No1.Postmanのインストール***

(1).Postmanのページにアクセスして、[Download the App]をクリックする。

Postname URL : https://www.postman.com/

<img width="441" alt="01.download.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/fa60288a-01b8-6a67-7210-19c0ac735c62.png">

(2).環境に合わせて[Windows 32-bit] or [Windows 64-bit]をクリックする 

<img width="600" alt="02.windows64bit.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/340f66c3-aadb-73b4-6141-64f415bce10b.png">

(3).ダウンロードが始まります。
<img width="300" alt="03.startdownload.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/5a4d2ec5-b397-e772-2219-024676c580ac.png">

(4).ダウンロードした[setup.exe]を実行致します。
<img width="300" alt="04.setupexe.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/5eb56572-ae26-4dc3-b33a-d641c4edf109.png">

(5).インストールが始まります。
<img width="300" alt="05.installing.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/79b0eead-1e3e-eb48-7904-ef038f009e78.png">

(6).Postmanの画面が表示されれば、インストール完了となります。
<img width="411" alt="06.installcomplete.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/4c9eca12-9f11-82ed-41b2-a200080e8f45.png">

***No2.Azure ADのテンプレート読み込み***

(1).Azure AD v2.0 protocolsテンプレートのインポート

https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth2-auth-code-flow
上記URLの『アクセストークンを要求する』のヒント欄に表示されている[Run in Postman]をクリックする。このリンクは、Azure AD v2.0 Protocols のテンプレートを Postman に読み込むためのリンクとなっており、OAuth のリクエストサンプルがインポートされ、このパラメーターを編集することによって、アクセストークンが取得できます。

<img width="424" alt="07.runinpostman.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/793a6674-939a-2bd8-0da7-d25346679322.png">

(2).[Postman for Windows]をクリックする。

<img width="300" alt="08.postmanforwindows.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/4bb6aeb9-57da-0d72-1ff1-33a7f8546240.png">

(3).[Open URL]をクリックする。

<img width="300" alt="09.openURL.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/c2fdb3b8-5af3-07a8-50d8-056a755b64a8.png">

(4).Azure AD v2.0 Protocolsがインポートされました。

<img width="300" alt="10.Addprotocol.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/6e4337c4-d1c4-585d-6a3b-30f700c1f085.png">

(5).Authorize Requestの編集
[OAuth 2.0 Authorization Code Flow]-[Authorize Request]-[Parmas]を選択する。

<img width="600" alt="11.AuthorizeRequest.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/ad446993-b6e9-cb83-92c5-2616aec23f85.png">

下記３点を編集致します。下記パラメーターは、Pythonの検証で使用したAzure ADのアプリ登録情報を使います。

|パラメーター|値|
|---|---|
|tenant ID|a94216cd-7c42-4b24-8ba0-ce5c210951bd|
|client_id|7e9cb366-34da-444f-bdae-f247d1e4311a|
|redirect_uri|http://localhost:5000/getAToken|

<img width="592" alt="1.authorize.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/ae20dc35-1e1c-0f94-7f49-d958f5c499d0.png">

(6).Token Requestの編集
[OAuth 2.0 Authorization Code Flow]-[Token Request]-[Body]-[x-www-form-urlencoded]を選択する。

<img width="600" alt="12.tokenrequest.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/f710feed-2ab1-3f13-7e60-21135fdec743.png">


下記4点を編集致します。こちらも、Pythonの検証で使用したAzure ADのアプリ登録情報を使います。

|パラメーター|値|
|---|---|
|tenant ID|a94216cd-7c42-4b24-8ba0-ce5c210951bd|
|client_id|7e9cb366-34da-444f-bdaef247d1e4311a|
|redirect_uri|http://localhost:5000/getAToken|
|client_secret|=EW0pc7AgEyFBzD92kpW[n:gefkoXJp:|

<img width="516" alt="3.request.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/7690ca1b-b78d-5abf-a2c0-c905733d2de2.png">

***No3.認証コードフローの確認***

0.Pythonを起動致します。 (#python app.py)

<b>◆フロー①.承認コードを要求する</b>
クライアントがユーザーを/authorizeエンドポイントへリダイレクトさせます。

編集したAuthorize RequestのURIをコピーして、ブラウザでアクセス致します。
<img width="594" alt="4.copyURL.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/432b33c3-7364-6e43-e190-3d946d0a1e21.png">

```
https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/oauth2/v2.0/authorize?

client_id=7e9cb366-34da-444f-bdae-f247d1e4311a
&response_type=code
&redirect_uri=http://localhost:5000/getAToken
&response_mode=query
&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&state=12345
```

●response_type
認証コードフローでは、codeを指定致します。

●scope
ユーザーに同意を求めるスコープのスペースで区切られたリストとなります。

|値|説明|
|---|---|
|openid|OpenID Connectを使用してサインインを行う場合、openidスコープを要求致します。|
|email|アプリがユーザーのプライマリ電子メールアドレスにemail要求の形式でアクセスできます。|
|offline_access|アプリは、ユーザーの代わりに、長期間にわたってリソースにアクセスできます。同意ページでは、このスコープは、"アクセス権を与えたデータへのアクセスを管理する。(Maintain access to data you have given it access to)"のアクセス許可として表示されます。|

●response_mode
結果として得られたトークンをアプリに返す際に使用できるメソッドを指定します。

|値|説明1|説明2|説明3|説明4|
|---|---|---|---|---|
|query|リダイレクトURL|302 Found|クエリー文字列パラメーター||
|fragment|URLフラグメント|302 Found|URLに#記号を使う(#+DOMのid値)|既定値|
|form_post|HTTPフォームポスト|200 OK||推奨|

●state
要求に含まれ、かつトークンの応答として返される値。
任意の文字列を指定する事ができ、クロスサイトリクエストフォージェリ攻撃を防ぐために通常、ランダムに生成された一意の値が使用される。

<b>◆フロー②アクセス許可に同意</b>

資格情報の入力と認証が求められ、同意の許可を与えると、Microsoft ID プラットフォームエンドポイントは、response_modeパラメーターで指定された方法(query)を使用して、指定されたredirect_uri(http://localhost:5000/getAToken) を使用してアプリに応答を返します。

<img width="312" alt="5.consent.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/f177f790-d6f7-0be8-2bd6-26d2e23b1a78.png">

<b>◆フロー③成功応答</b>
response_mode=queryを使用した場合の成功応答となります。
フロー①で指定したredirect_url=http://localhost:5000/getAToken 宛に応答を返しております。応答には、アプリが要求したauthorization_codeが含まれております。

```
GET http://localhost:5000/getAToken?code=OAQABAAIAAABeAFzDwllzTYGDLh_qYbH8Ok8oveg3-08SNK-cebpBUdbxcJQfToINXwrysbQpGR3qzq1XHVVlVh9Xd1t2U7KSga4t3Z32PmByqoiv2LfuN34Zrc5R-mEo1LOyfVljMMutIJv3Ptk5qucX8hHUnLH13u7M9rqm1X-xLEl1uNkRcuiPonfjZj8zrPUyQ-C3KykY2h9-mFac9_xJriHOeLn0E4Bk3H5TbJsKzIudf4kHCI001KheR4RfdP7kkxUz8jBjUXj6q3SM0HySugeCiK6E_LCuG7EZCB_2-GbMeKQ-R8XAxh5b10lFZin2xBFlFsrIRDwCkjrwfpJC60vZqRnE4nCdyK0_ZPHZboECFQHPRANCe6nvz6XBqptuQAODlFo5J3tzowTVDWOshmlam0EjNUI4qbOtNIQ5HPrtLUPj3VOGsvsWXMuq5VE2Noqku58odx51bx2w-1W5OjL_hwygWXwMXwMxkzC22GoID_WUXezsHl0tEi6U454_9j4p9FSx5MLE1K8DsBmDJlUsEO4IoxVsLTIkhnlDaCRC1kQS_jxg5m7J5te6Luji8-ZkbRKZ_W9iSuWGtXglBk0DcvTt_cdLVc9675p1B1xFxJMexvCfC4934AjQedAf1fA169t7fZj-G4sZPtJFltc3ZKIabFZ78jx39I5C9_Eri70YeyAA
&state=12345
```

●state
フロー①で指定したstateが含まれます。要求と応答が同一である事を確認するためにstate=12345が含まれている事を確認致します。

●code
アプリが要求したauthorization_code。このコードを使用して、アクセストークンを要求致します。有効期限は、通常10分後には、期限切れとなります。

<b>◆フロー④アクセストークンを要求する</b>

*1.authorization_codeを取得したら、access_tokenを要求致します。これを行うには、POST要求を/tokenエンドポイントに送信します。
*2.postmanを使って、アクセストークンを要求致します。

1.アクセス許可を承諾すると#python app.pyのログにauthorization_codeが出力されますので、これをコピー致します。
<img width="720" alt="6.code.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/ea7e1ea4-7bfe-359f-69af-9f664143f3a4.png">

2.コピーしたauthorization_codeをToken RequestのCode欄に貼り付け、[Send]をクリック致します。
<img width="962" alt="6.5.sendbutton.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/fd69b360-4a21-bc95-05ab-9626fb748505.png">

```
POST https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/oauth2/v2.0/token

client_id=7e9cb366-34da-444f-bdaef247d1e4311a
&scope=https://graph.microsoft.com/mail.read
&redirect_uri=http://localhost:5000/getAToken
&grant_type=authorization_code
&client_secret==EW0pc7AgEyFBzD92kpW[n:gefkoXJp:
&code=貼り付けたauthrization_codeとなります。
```
●grand_type
承認コードフローでは、authorization_codeを指定致します。

●client_secret
Webアプリの場合は、必須となります。アプリ登録ポータルで作成したアプリケーションのシークレットになります。

<b>◆フロー⑤成功応答</b>
取得したトークンは、下記となります。(JSONとなります。)

```
{
    "token_type": "Bearer",
    "scope": "openid profile mail https%3A%2F%2Fgraph.microsoft.com%2Fmail.read https%3A%2F%2Fgraph.microsoft.com%2FUser.ReadBasic.ALL",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "xxxx...",
    "refresh_token": "xxxx......",
    "id_token": "xxxx......",
}
```

●access_token
要求されたアクセストークン。アプリはこのトークンを使用して、保護されたリソースに対し、本人性を証明致します。

●token_type
Azure ADでサポートされるのはBearerタイプのみとなります。

●expires_in
アクセストークンの有効期間 (秒)。通常、1時間以内に期限切れとなります。

●scope
access_tokenが有効である範囲となります。

●id_token
JSON Web トークン (JWT)。アプリは、このトークンのセグメントをデコードすることによって、サインインしたユーザーに関する情報を要求することができます。

●refresh_token
OAuth 2.0 更新トークン。offline_accessスコープが要求された場合のみ提供されます。更新トークンは、クライアントが既に同意を受け取っているすべてのアクセス許可に対して有効です。

取得したトークンは、下記となります。
<img width="598" alt="7.accesstoken.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/63ff1cf6-e87e-07eb-083e-220e36e072e6.png">
<img width="338" alt="8.idtoken.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/d26ae761-ad9a-9efe-ee5f-03174e457183.png">

*id_token
<img width="653" alt="9.jwt_idtoken.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/5f672130-8c9f-5fc2-7bd5-d5d139cc4ab9.png">

*access_token
<img width="642" alt="10.jwt_accesstoken.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/58c685c4-64a7-d076-be0c-3a41ae3a65c0.png">

これにて、認可コードフローの確認は、終了となります。

++追加情報です++
Cookies
<img width="786" alt="Cookie.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/5a5de77a-c819-ea3f-0a2b-b37407d1d6f4.png">
headers
<img width="842" alt="Headers.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/612a1bfe-1e97-bed5-0b28-042486877082.png">


最後に
----
インプリシットフローに比べて、ひと手間増えることになりますが、、これがセキュリティ向上につながると考えると必要なフローだと思いました。次回は、Azure AD B2Cの検証結果を投稿していきたいと思います。

最後に、私の情報が皆様のお役に立てれば、幸いでございます！！