前回から引き続きで、以下のイメージを実装したものを動かしてみるところからです。(図はこちらから引用)。
結局のところ、今回書いた認証サーバーの役割をするAzure Functionsの実装と、最後に載せてるクライアント側を想定したコンソールアプリクラスがあればいいだけなオチではあります。
Overview
- 準備1:DocumentDBのインスタンス作成とコレクションの作成(前回)
- 準備2:ユーザー、パーミッションの作成(前回)
- コンソールアプリから動作検証 (←ここから)
- Azure Functionsを使って動作検証
最終形のコードはブログの下の方にあります♪
Environment
- Visual Studio 2017 Enterprise (RC)
- DocumenDB Core (v1.0.0)
- .NETCore.App (v1.1.0)
準備1:DocumentDBのインスタンス作成とコレクションの作成
コンソールアプリで動作検証
では、さっそく手抜き感溢れるConsoleアプリで動作確認します。
このコードは、前回実装したResourceTokenDemo
クラスに以下のコードを追加してしまいます。
コンソールアプリで、このクラスをnew
して、3行目のRunDemoAsync
メソッドをコールして動作確認です。
76行目のGetResourceTokenAsync
メソッドでは、DocumentDBのURIとプライマリーキーを使ってトークンを取得します。つまり、このメソッド(とそれに絡む変数とか)だけが、本来は"Mid-tier service"の位置づけとなるサーバー側に実装するイメージです。
6行目で、Col1コレクションのReadOnly権限のリソーストークン」を取得しています。
8行目で「Col2コレクションのAll権限」のリソーストークンを取得しています。
25行目のReadAndInsertDocumentsAsync()
メソッドに1st引数は操作するコレクション、2nd引数は権限が付与されたリソーストークンを渡します。そのコレクションに対して、権限が付与されたリソーストークンを使ってDocumentDBの読み取りとデータ挿入を行います。
ということで、4通りの組み合わせで実行しました。
- 「Col1」コレクションに対して、「Col1のReadOnly権限」でアクセス
- 「Col1」コレクションに対して、「Col2のALL権限」でアクセス
- 「Col2」コレクションに対して、「Col2のALL権限」でアクセス
- 「Col2」コレクションに対して、「Col1のReadOnly権限」でアクセス
実行結果は、想像通り権限が正しく適用された結果となりますね。
Azure Functionsで動作検証
今回Functionsへのアクセスには認証の実装をしていないのですが、本来はそれをしないと意味がない...(でも今回は実装しない)っていう前提で進めます。
私は既に男らしく? Visual Studio 2015 をアンインストール済みなので、Azure PortalからFunction Appをコーディングします。
ここでは、所都合により.NET Framework4.6ベースでコーディングです。
Function Appの作成
これはポチポチするだけなので、本家サイトのリンクをペタ。C#でHTTPトリガーのFunctionを作成します。
今回私のFunctionの名称は、デフォルトでつけられたHttpTriggerCSharp1
という名称で進めています。
NuGet からライブラリを読み込む
Microsoft.Azure.DocumentDB
のライブラリをインポートします。
まずは、作成したFunctionのブレードの下の方「Function Appの設定」をクリックし、「AppService エディターに移動」をクリックします。
エディターが開いたら、「WWWROOT」のあたりにカーソルをあて、ファイルの追加をします。ファイル名は、「project.json」にする必要があります。
「project.json」は、以下のように書きます。
現時点で最新の「"Microsoft.Azure.DocumentDB": "1.11.4"」を追加してあげます。これで、ライブラリの読み込み設定が完了です。
環境変数を設定
DocumentDBのURIとアクセスキーを環境変数に入れてしまいましょう。
まず、Functionのブレードに戻ります。先ほど同様に「Function Appの設定」を開いて、「アプリケーション設定の構成」を開きます。
「アプリ設定」に、キーと値を追加します。今回は以下のように設定しました。
- キー:Ddb_Uri の値にDocumentDBのURIを設定
- キー:Ddb_AccountKey の値にDocumentDBのプライマリーキー
Functionsのコーディング
あとは、Azure Portalでコードを直接書きます。
今回は、HTTPのGETメソッドで、リソーストークン取得に必要な必要なパラメーター(databaseId, userId, permissionId)を受け取り、DocumentDBへアクセス→取得したリソーストークンをテキストで返すというコードです。テキストを指定しないとJsonで返そうとして、リソーストークンにダブルクォーテーションがついちゃうので、使い方に注意ですね。
ポータルからテスト実行してみると、トークンが取れてることが確認できます。
コンソールアプリからFunctionsをコールしてトークンを取得
前回のコードのGetResourceTokenAsync
メソッドを変更し、FunctionsのURIとかHTTPのGetのURIを構築するメソッドを追加しました。
コンソールアプリを実行してみると無事に想定通りの動作します♪。
最後に
ごちゃごちゃとコードの追加追加をしてしまったので、ResourceTokenDemo
クラスの最終形を...
あと、struct...
ついでにコンソールからの実行コードです。
最後に
XamarinとDocumentDBに関する以下のリンクで紹介されている中で、
この図の赤線の部分をAzure Functionsで実装したサンプルという話だったのです♪。
試したことを長々と書いてしまいましたが、Functionsのコード書いてクライアント側からのアクセスを書くだけの方がシンプルにまとまりよかったなと...ちょっと後悔した今日この頃でした。