読者です 読者をやめる 読者になる 読者になる

BEACHSIDE BLOG

MicrosoftとかC#を好むレンジャーの個人的メモ

DocumentDB - リソーストークンを使ったアクセス - 2/2 ( Access to DocumentDB with resource tokens )

前回から引き続きで、以下のイメージを実装したものを動かしてみるところからです。(図はこちらから引用)。

f:id:beachside:20170206180238p:plain

結局のところ、今回書いた認証サーバーの役割をするAzure Functionsの実装と、最後に載せてるクライアント側を想定したコンソールアプリクラスがあればいいだけなオチではあります。

Overview

最終形のコードはブログの下の方にあります♪

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権限」でアクセス

実行結果は、想像通り権限が正しく適用された結果となりますね。

f:id:beachside:20170207185714p:plain

Azure Functionsで動作検証

今回Functionsへのアクセスには認証の実装をしていないのですが、本来はそれをしないと意味がない…(でも今回は実装しない)っていう前提で進めます。
私は既に男らしく? Visual Studio 2015 をアンインストール済みなので、Azure PortalからFunction Appをコーディングします。
ここでは、所都合により.NET Framework4.6ベースでコーディングです。

Function Appの作成

これはポチポチするだけなので、本家サイトのリンクをペタ。C#でHTTPトリガーのFunctionを作成します。

docs.microsoft.com

今回私のFunctionの名称は、デフォルトでつけられたHttpTriggerCSharp1という名称で進めています。

NuGet からライブラリを読み込む

Microsoft.Azure.DocumentDBのライブラリをインポートします。
まずは、作成したFunctionのブレードの下の方「Function Appの設定」をクリックし、「AppService エディターに移動」をクリックします。

f:id:beachside:20170207201727p:plain

エディターが開いたら、「WWWROOT」のあたりにカーソルをあて、ファイルの追加をします。ファイル名は、「project.json」にする必要があります。

f:id:beachside:20170207201845p:plain

「project.json」は、以下のように書きます。

f:id:beachside:20170207201957p:plain

現時点で最新の「"Microsoft.Azure.DocumentDB": “1.11.4"」を追加してあげます。これで、ライブラリの読み込み設定が完了です。

環境変数を設定

DocumentDBのURIとアクセスキーを環境変数に入れてしまいましょう。
まず、Functionのブレードに戻ります。先ほど同様に「Function Appの設定」を開いて、「アプリケーション設定の構成」を開きます。

f:id:beachside:20170207202308p:plain

「アプリ設定」に、キーと値を追加します。今回は以下のように設定しました。

  • キー:Ddb_Uri の値にDocumentDBのURIを設定
  • キー:Ddb_AccountKey の値にDocumentDBのプライマリーキー

f:id:beachside:20170207222759p:plain

Functionsのコーディング

あとは、Azure Portalでコードを直接書きます。

今回は、HTTPのGETメソッドで、リソーストークン取得に必要な必要なパラメーター(databaseId, userId, permissionId)を受け取り、DocumentDBへアクセス→取得したリソーストークンをテキストで返すというコードです。テキストを指定しないとJsonで返そうとして、リソーストークンにダブルクォーテーションがついちゃうので、使い方に注意ですね。

ポータルからテスト実行してみると、トークンが取れてることが確認できます。

f:id:beachside:20170207223406p:plain

コンソールアプリからFunctionsをコールしてトークンを取得

前回のコードのGetResourceTokenAsyncメソッドを変更し、FunctionsのURIとかHTTPのGetのURIを構築するメソッドを追加しました。

コンソールアプリを実行してみると無事に想定通りの動作します♪。

最後に

ごちゃごちゃとコードの追加追加をしてしまったので、ResourceTokenDemoクラスの最終形を…

 

あと、struct…

 

ついでにコンソールからの実行コードです。

最後に

XamarinとDocumentDBに関する以下のリンクで紹介されている中で、

How To Build Planet Scale Mobile App in Minutes with Xamarin and DocumentDB | Blog | Microsoft Azure

この図の赤線の部分をAzure Functionsで実装したサンプルという話だったのです♪。

f:id:beachside:20170208150952p:plain

試したことを長々と書いてしまいましたが、Functionsのコード書いてクライアント側からのアクセスを書くだけの方がシンプルにまとまりよかったなと…ちょっと後悔した今日この頃でした。

参考

docs.microsoft.com

docs.microsoft.com