【Microsoft ID プラットフォーム】(Azure AD) ASP.NET Core Web アプリ編

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

SPA (Node.js)
https://qiita.com/Design_Tshirt7/items/553958e3724cc3718aa9
ASP.NET
https://qiita.com/Design_Tshirt7/items/c282d645c2117be12d4e

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

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.参照ページ

『クイック スタート:ASP.NET Core Web アプリに Microsoft サインインを追加する』

https://docs.microsoft.com/ja-jp/azure/active-directory/develop/quickstart-v2-aspnet-core-webapp

2.登場人物
1.Identity Provider (Azure AD)
* オンマイクロソフトアカウントを使います。
2.Relying Party (ASP.NET Core)
　* Visual Studio 2019 (事前の準備をお願い致します。インストール方法は割愛させて頂きます)
* サンプルコード (以降の手順でダウンロード致します。)

3.手順
◆手順 1:アプリケーションの登録

1.Azure portal(https://portal.azure.com) にサインインします。

2.[ホーム]-> [Azure AD Active Directory] -> [アプリの登録]へ進む。

<img width="200" alt="1.appregistration.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/9696218d-8fac-6b4f-7697-f41951f8c086.png">

3.[新規登録] をクリックします。

<img width="400" alt="2.newregistration.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/a63fd855-5880-436c-136e-d7d8ab45bca6.png">

4.アプリケーション登録で下記項目を選択して、[登録]をクリック。
(1).名前欄：任意のアプリケーション名を入力
(2).サポートされているアカントの種類：この組織ディレクトリのみに含まれるアカウント
(3).リダイレクトURL：空白　=> (後ほど、入力されます。)

<img width="400" alt="1registartion.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/7ea671f6-3da3-0f48-3d49-4aa3a1de7e89.png">

5.登録したアプリケーションが表示されますので、[クイックスタート]をクリック。

<img width="400" alt="2.quickstart.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/4fa3cd46-e561-bc7d-ced7-6f0e240594e3.png">

6.クイックスタートガイドの[ASP.NET Core]をクリック。

<img width="400" alt="3.asp.netcore.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/45c836cc-1efa-730b-d4fc-8f51d1ffe15b.png">

7.[これらの変更を行います]をクリック。

<img width="400" alt="4.change.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/991d54a0-da78-2502-2ea3-6c3558f890c2.png">

8.下記構成内容が表示されますので、[更新する]をクリック。
(1).リダイレクト URI : 
https://localhost:44321
https://localhost:44321/signin-oidc
(2).ログアウトURL
https://localhost:44321/signout-callback-oidc
(3).IDトークン：Ture

<img width="400" alt="5.update.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/30a7bcfe-9f84-af36-f9aa-ddb671b2c507.png">

*下記の[認証]画面から構成の反映を確認可能です。

<img width="600" alt="6.authN.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/182d2ee1-edf4-576b-37d9-3d4bda27d767.png">

◆手順 2:プロジェクトのダウンロード
1.Visual Studio 2019 を使用して IIS Expressサーバーでプロジェクトを実行致しますので、プロジェクトファイルをダウンロードします。

プロジェクトファイル：active-directory-aspnetcore-webapp-openidconnect-v2-aspnetcore2-2.zip

<img width="400" alt="1.download.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/cbfc31a8-3c57-c2d7-5ef0-910156abed9e.png">

◆手順 3:Visual Studio 2019 の構成

1.ローカルフォルダーに zip ファイルを展開します。

<img width="400" alt="1.folder.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/05f0913e-66fc-3348-fe74-985b237ecee9.png">

2.Visual Studio 2019を起動して、[プロジェクトやソリューションを開く]をクリック。
<img width="400" alt="2.open.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/6425e637-fb69-8e31-c952-5b6a0b6428e2.png">


3.ソリューション(WebApp-OpenIDConnect-DotNet.sln)を選択して[開く]をクリック。

<img width="400" alt="2.ASP.NET.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/d4e4fecf-8634-d5fe-7aa9-6ab4f203492d.png">

7.[ソリューションエクスプローラー]->[appsettings.json] を選択してクリック。

<img width="299" alt="3.appsettings.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/0632605b-e32a-64b0-33aa-fdc1552772d9.png">

8.appsettings.jsonファイルを編集します。
(Domain, tenant ID, client IDを修正)

<img width="369" alt="4.changeappsettings.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/ebdf35c1-10f6-2019-8cf8-371e057e09df.png">

◆手順4: サインイン

事前準備//
*Fiddlerでパケットキャプチャ。
*ダウンロードしたコアプロジェクトサンプルの仕組みをきちんと確認。
<img width="400" alt="flow.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/288134b1-43da-36e6-f2fc-f496a2c448da.png">

<b>0.IIS Expressを使って、Webサービスを起動。</b>

<img width="307" alt="1.iis.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/1d2c126f-c34c-9c60-2d15-c5023dbc265e.png">

<b>1.ログイン </b>
https://localhost:44321
にアクセスするとリダイレクトで認証画面に遷移しましたので、2-1からスタートなります。

<b>2.認証リクエストの流れ (RPからWebブラウザを経てIDプロバイダへ)</b>
●2-1.リダイレクト
RP(ASP.NET Core)は、HTTPステータスコード 302を返す。
302を返す際には、Locationヘッダーに『認可エンドポイント』(IDP)のURLが含まれる。

```
HTTP/1.1 302 Found
Location: https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/oauth2/v2.0/authorize
?client_id=ba56b010-e58f-4f14-b313-579bdc283094
&redirect_uri=https://localhost:44321/signin-oidc
&response_type=id_token
&scope=openid profile
&response_mode=form_post
&nonce=63717157366821712GUtM
```

●2-2.Azure ADエンドポイント情報 (/.well-known/openid-configuration) の確認

GET https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/v2.0/.well-known/openid-configuration HTTP/1.1
User-Agent: Microsoft ASP.NET Core OpenIdConnect handler

```
"authorization_endpoint":"https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/oauth2/v2.0/authorize"
"token_endpoint":"https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/oauth2/v2.0/token"
"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo"
```

●2-3.認証リクエスト (WebブラウザからIDプロバイダへ)

```
GET https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/oauth2/v2.0/authorize
?client_id=ba56b010-e58f-4f14-b313-579bdc283094
&redirect_uri=https://localhost:44321/signin-oidc
&response_type=id_token
&scope=openid profile
&response_mode=form_post
&nonce=637171573668217126.YTF
&state=CfDJ8DactgIdPTJKtPLtz1df2Ae
```
*パケットキャプチャで確認
<img width="700" alt="1.AuthRequest2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/ef5767c7-e536-0735-d81c-bcc0d96f0b10.png">

<b>3.資格情報(ID/パスワード)を入力</b>

<b>4.認証レスポンスの流れ (IDプロバイダからWebブラウザを経てRP)</b>
●4-1.同意
<img width="307" alt="1.consent.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/5068fad3-93e8-e3fb-6d48-023ba830d53e.png">

●4-2.認証レスポンス (IDプロバイダからWebブラウザ)
★IDトークン取得

```
POST https://login.microsoftonline.com/a94216cd-7c42-4b24-8ba0-ce5c210951bd/Consent/Set HTTP/1.1
name="id_token" value="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkhsQzBSMTJza3hOWjFXUXdtak9GXzZ0X3RERSJ9.eyJhdWQiOiJiYTU2YjAxMC1lNThmLTRmMTQtYjMxMy01NzliZGMyODMwOTQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vYTk0MjE2Y2QtN2M0Mi00YjI0LThiYTAtY2U1YzIxMDk1MWJkL3YyLjAiLCJpYXQiOjE1ODE1NjAyODEsIm5iZiI6MTU4MTU2MDI4MSwi
```

*パケットキャプチャで確認
<img width="500" alt="2.id_token.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/0e2e8316-c353-e490-f7b0-e2e0dea45402.png">

★ヘッダー、ペイロードを確認。
<img width="676" alt="jwt.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/8573c666-49cc-b688-c926-3e9519e6fbf4.png">

★アクセストークン
Locationヘッダのフラグメントには、値はありませんでした。
(取得するには、&response_type=id_token+codeに変更する必要有り)
*パケットキャプチャで確認
<img width="700" alt="3.access_token.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/dc0f1638-3324-5258-eaa4-1bbbf100baca.png">

<b>5.サインイン</b>
無事、サインインできました。

<img width="400" alt="2.login.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/709c58ce-5b56-0dc4-34c4-60202e2d53f6.png">

最後に、今回、取得したFiddlerのパケットの流れとなります。
<img width="500" alt="0.flow_fiddler.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579284/aa13c6aa-1883-36b3-8ede-e23f7f4ae103.png">

まとめ
-----
次回は、Java Web アプリ (Tomcatの直deploy)の検証を予定しております。今度は、認可コードフローとなりますので、もう一度、きちんとOIDCのシーケンスを勉強し直すことを決意致しました。

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