御成門プログラマーの日記

Microsoft AzureやAngularなどの技術情報を発信します

Azure Key Vaultのシークレットに登録した値を取得する【.net】

Azure上でキーや接続文字列などを扱うときには、AzureKeyVaultを使います。
今回はそんなAzureKeyVaultのシークレットに登録した値を.netのコードで
取得する方法を紹介します。

Azure Key Vaultとは

docs.microsoft.com

Azure Key Vault は、シークレットを安全に保管し、それにアクセスするためのツールです。
シークレットは、API キー、パスワード、証明書など、アクセスを厳密に制御する必要がある任意のものです。

  • シークレットの管理・・・シークレットには接続文字列、APIキー、パスワードなどセキュアに管理する必要のあるものを格納する

  • 暗号化キーの管理・・・データの暗号化に使用される暗号化キーの作成と制御が可能

  • 証明書の管理・・・Azureおよび内部リソースで使用するためのSSL証明書をプロビジョニング、管理、デプロイする

AzureポータルでKeyVaultを作成する

まずはAzureポータルでKeyVaultを作りましょう。

名称 設定値
名前 <各自自由>
サブスクリプション <各自自由>
リソースグループ <各自自由>
場所 <各自自由>
価格レベル 今回の要件は"標準"で大丈夫
アクセスポリシー そのまま
仮想ネットワークアクセス そのまま

AADにKeyVault認証用のアプリ(サービスプリンシバル)を作成する

KeyVaultから値を取得する権限を持ったアプリ(サービスプリンシバル)を作成する必要があります。
Azureポータルから
AzureActiveDirectory→アプリの登録→新しいアプリケーションの登録
下記を参考に値を入力して、作成をクリックします。

f:id:tt-suzukiit:20181114183307p:plain

名称 設定値
名前 <各自自由>
アプリケーションの種類 Webアプリ/API
サインオンURL とりあえず適当なURL(例:http://test1.contoso.com)

作成したアプリを開きます。
ここで"アプリケーションID(クライアントID)"を控えておきます。

パスワードの設定を行います 設定→キー→パスワード

f:id:tt-suzukiit:20181114183132p:plain
一度保存した値は表示されません。

名称 設定値
説明 <各自自由>
有効期限 <各自自由>
保存すると、自動的に作成されるのでそのまま

保存したときに表示される"値(クライアントシークレット)"を控えておきます。

KeyVaultにアプリ(サービスプリンシバル)を登録します

最初に作成したKeyVaultの画面に戻ります。 アプリ(サービスプリンシバル)を登録します。 アクセスポリシー→新規追加

f:id:tt-suzukiit:20181114182947p:plain

名称 設定値
テンプレートからの構成 未選択
プリンシバルの選択 先ほど作成したアプリを選択
キーのアクセス許可 未選択
シークレットのアクセス許可 取得を選択
証明書のアクセス許可 未選択
承認されているアプリケーション 未選択

これでアクセスポリシーの設定は完了です

KeyVaultのシークレットに保存する値を設定する

KeyVaultの画面→シークレット→生成/インポート

f:id:tt-suzukiit:20181114182826p:plain

名称 設定値
アップロードオプション 手動
名前 <各自設定>
保存したい値を入力
コンテンツの種類 未入力
アクティブ化する日 未チェック
有効期限を選択しますか 未チェック
有効ですか はい

アプリケーション側でシークレットを取得する処理を記述する

NugetでMicrosoft.Azure.KeyVaultをインストールします。
下記のコードでシークレットに登録した値を取得することができました。

using Microsoft.Azure.KeyVault;

public static async Task<string> GetSecret()
{
    return await GetSecretAsync("https://<作成したKeyVault名>.vault.azure.net/", "<KeyVaultに作成したシークレットの名称>");
}

private static async Task<string> GetSecretAsync(string vaultUrl, string vaultKey)
{
    var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessTokenAsync), new HttpClient());
    var secret = await client.GetSecretAsync(vaultUrl, vaultKey);
    return secret.Value;
}

private static async Task<string> GetAccessTokenAsync(string authority, string resource, string scope)
{
    var appCredentials = new ClientCredential("<作成したアプリのClientID>","<作成したアプリのClientSecret>");
    var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
    var result = await context.AcquireTokenAsync(resource, appCredentials);
    return result.AccessToken;
}