Office 365 Rest APIに対してJWT Bearer Tokenフローで利用するアプリケーションを作るにあたって、まずは、ADAL(Active Directory Authentication Library)を利用したチュートリアルAuthenticating to Azure AD in daemon apps with certificatesを試してみました。
このチュートリアルは、Azure ADの認証シナリオのうち、「クライアント資格情報を使用したサービス間の呼び出し」を実装しています。
このシナリオでは、Azure ADは、OAuthの以下の仕様をサポートします。
- Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
- JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
ADALを利用すると、設定と秘密鍵を指定するだけで、JWT(Json Web Token)を使ってAPIのアクセストークンを取得するリクエストの実装はライブラリにおまかせできますが、ライブラリが内部でやっていることを図にしてみると以下のようになります。
(クライアント資格情報を使用したサービス間の呼び出しの図と同じです)
以下は、チュートリアルを試してみた内容になります。
クライアント・アプリケーション TodoListDaemonWithCertの追加
Azure AD ディレクトリの[アプリケーション]タブを開き、フッターの[追加]をクリックし、アプリケーションの作成をはじめます。
名前に”TodoListDaemonWithCert”と入力し、右下の[->]アイコンをクリック
[サインオンURL]および[アプリケーション ID / URI]は、どちらもhttp://TodoListDaemonWithCert
を入力します。
ユーザーにログインを要求しないクライアントアプリなので、値はURI形式であればなんでも良いようです。
右下のチェックアイコン(完了)をクリックするとアプリケーションが追加されます。
APIサービス TodoListServiceの追加
再度、ディレクトリの[アプリケーション]タブで、フッターの[追加]をクリックしてアプリケーションの作成をはじめます。
名前は”TodoListService”と入力し、右下の[->]アイコンをクリック
[サインオンURL]に”https://localhost:44321″を、[アプリケーション ID / URI]には、”https://<テナント名>/TodoListService”を入力します。
右下のチェックアイコン(完了)をクリックして、アプリケーションの作成を完了します
自己署名証明書を作成
クライアント・アプリケーションTodoListDaemonWithCertを認証するためにAzure ADに登録する証明書を作成します。
makecertコマンドを使って自己証明書を作成します。
makecertの使い方については、Makecert.exe (証明書作成ツール)を参照ください。
makecertコマンドは、Visual Studio 2015をインストールすると追加される開発者コマンドプロンプト for 2015を開くとパスが通っているので、それを使います。
[スタート] > [すべてのプログラム] > [Visual Studio 2015] > [開発者コマンドプロンプト for 2015]で開き以下のコマンドを実行します
> makecert -r -pe -n "CN=TodoListDaemonWithCert" -ss My -len 2048 TodoListDaemonWithCert.cer
Succeeded
-peオプションを指定すると、実行したPCに秘密キーを持った証明書がインストールされます。
インストールされた証明書はcertmgr.mscで確認できます。
参考: 証明書を表示または管理する
Azure ADに証明書を追加する
作成した証明書を、Azure ADのクライアント アプリケーションに登録していきます。
証明書から証明書データとフィンガープリントを取り出しBase64エンコードした値と、GUIDのキーIDを生成します。
PowerShellを開き以下のコマンドを実行します
> $cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
> $cer.Import("TodoListDaemonWithCert.cer")
> $bin = $cer.GetRawCertData()
> $base64Value = [System.Convert]::ToBase64String($bin)
> $bin = $cer.GetCertHash()
> $base64Thumbprint = [System.Convert]::ToBase64String($bin)
> $keyid = [System.Guid]::NewGuid().ToString()
実際に実行したPowerShellウィンドウのスクリーンショットです
Azure ADのアプリケーション[TodoListDaemonWithCert]の[構成]を開き、フッターの[マニフェストの管理] > [マニフェストのダウンロード]をクリックします。
[マニフェストのダウンロード]をクリックすると、マニフェストファイル<クライアントID>.json
がダウンロードされます。
マニフェストのkeyCredentials
に、PowerShellで証明書からとりだした値をセットします。
"keyCredentials": [
{
"customKeyIdentifier": "<$base64Thumbprintの値>",
"keyId": "<$keyidの値>",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"value": "<$base64Valueの値>"
}
],
実際に値をセットした場合以下のようになります
"keyCredentials": [
{
"customKeyIdentifier": "esfAIInO5Hg4wIMiEnZ5a2N/CeI=",
"keyId": "ac28c92a-1001-4384-ad90-2dcb0056e923",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"value": "MIIDBTCCAfGgAwIBAgIQ9/XgQ2766JdP ...省略... 4HcoQvvVkfEZQKtK"
}
],
マニフェストファイルを保存したら、[マニフェストの管理] > [マニフェストのアップロード]からアップロードします。
Azure ADの情報をプロジェクトに設定
クローンまたはzipダウンロードしたソリューションをVisual Studio 2015で開ます。
TodoListDaemonWitCert/App.configを開きappSettings
の各項目を以下のように設定します。
// TodoListDaemonWitCert/App.config
<appSettings>
<add key="ida:AADInstance" value="https://login.microsoftonline.com/{0}" />
<add key="ida:Tenant" value="trial365.onmicrosoft.com" />
<add key="ida:ClientId" value="80ff11d6-e7f0-4c8c-beff-ff0ca1f8093d" />
<add key="ida:CertName" value="CN=TodoListDaemonWithCert" />
<add key="todo:TodoListResourceId" value="https://trial365.onmicrosoft.com/TodoListService" />
<add key="todo:TodoListBaseAddress" value="https://localhost:44321" />
</appSettings>
- ida:AADInstance:
https://login.microsoftonline.com/{0}
のまま - ida:Tenant: ディレクトリのドメイン、Office 365のドメインの場合は、
<テナントID>.onmicrosoft.com
- ida:ClientId: 作成したアプリケーションのクライアントID
- ida:CertName: 作成した証明書のコモンネーム、makecertコマンドの
-n
オプションに指定した値 - todo:TodoListResourceId: Web APIのアプリケーション ID / URI。
https://<ディレクトリのドメイン>/TodoListService
TodoListService/Web.confgを開きappSettings
の各項目を以下のように設定します。
//TodoListService/Web.confg
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:Tenant" value="trial365.onmicrosoft.com" />
<add key="ida:Audience" value="https://trial365.onmicrosoft.com/TodoListService" />
</appSettings>
- ida:Tenant: ディレクトリのドメイン、Office 365のドメインの場合は、
<テナントID>.onmicrosoft.com
- ida:Audience: Web APIのアプリケーション ID / URI。
https://<ディレクトリのドメイン>/TodoListService
IISに証明書を追加
クライアント・アプリケーションからIISに自己証明書でSSL通信するためには、CN=localhost
の証明書を信頼された証明書としてIISに登録する必要があります。
管理者でPSを開きます
以下のコマンドで証明書のThumbprintを確認します
> dir Cert:\LocalMachine\My
Directory: Microsoft.PowerShell.Security\Certificate::LocalMachine\My
Thumbprint Subject
---------- -------
C24798908DA71693C1053F42A462327543B38042 CN=localhost
証明書をRootに追加します
> $cert = (get-item cert:\LocalMachine\My\C24798908DA71693C1053F42A462327543B38042)
> $store = (get-item cert:\Localmachine\Root)
> $store.Open("ReadWrite")
> $store.Add($cert)
> $store.Close()
以下のコマンドでCN=localhostが追加されたことを確認できます
> dir Cert:\LocalMachine\Root
以下は実際にコマンドを実行したスクリーンショットです
動作確認
以上で、クライアントアプリケーションTodoListDaemonWithCertを実行して、Web API TodoListServiceへのアクセスを確認する準備が整いました。
Visual Studioでソリューションを実行し、APIアプリが正常に動作しているかブラウザで確認しておきます。
このとき、エラー「Runtime error: Could not load file or assembly ‘System.Web.WebPages.Razor, Version=3.0.0.0」が表示される場合は、プロジェクトに含まれるパッケージのバージョンが古いので更新する必要があります。
パッケージの更新は、Visual Studioの[ツール] > [NuGet パッケージ マネージャー] > [ソリューションの NuGet パッケージの管理]を開くと[更新プログラム]タブで新しいバージョンがあるパッケージを確認、インストールできます。
参考: Runtime error: Could not load file or assembly ‘System.Web.WebPages.Razor, Version=3.0.0.0
クライアントアプリを起動すると、以下のようにTodoの追加と一覧が交互に実行されていることが確認できます。
以上で、チュートリアルの確認は完了です。
Azure ADの認証シナリオ「クライアント資格情報を使用したサービス間の呼び出し」について、利用方法が確認できたことになります。