2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Spring Boot から Key Vault の値を Managed IDを使って読み取る

Last updated at Posted at 2021-05-05

Spring Boot から Key Vault の値を Managed IDを使って読み取る

今回は、Managed ID(管理ID)についてです。Managed IDについては、以下にがっつりと解説がありますが、簡単に言ってしまえば、例えば、WebApps から SQL DB 、ストレージ、Key Vault など他コンポーネントのアクセスにパスワードなどのシークレットを必要としない仕組みとなります。

Azure リソースのマネージド ID | Microsoft Docs

もちろん、WebAppsから、他のAzureリソースへ勝手にアクセスできるわけではありませんから、Azure 上でしかるべき手順を踏んで設定を行っておく必要があります。設定は、ポータル以外にも Azure CLI などのコマンドラインツールでも可能です。

WebApps + Key Vault での例

先だっての記事の続きというわけではありませんが、前提とする環境は、 Spring Boot + WebApps/Key Vault で試してみたいと思います。

WebAppsでの設定

ポータルで確認すると、WebApps には、 「ID」という管理項目があります。Managed ID を有効にするには、ここでこの機能をオンにします。

オンにするとなにが起こるのかというと、Azure AD 上に、このWebAppsに紐づいたサービスプリンシパルと呼ばれる資格情報がこっそり作成されます。WebApps 側の設定はこれだけです。この時に表示されるオブジェクトID (クライアントID)は、あとで必要ですのでメモっておきます。またサービスプリンシパルの名前はWebAppsの名前と同じ名前になります。後ほどアクセス権を設定するところで使います。

image.png

Key Vault での設定

Key Vaultには、キー、シークレット、証明書の3つの種類をストアできます。いわゆる構成設定値のような、キーバリュー型のものはシークレットに保存します。以下のクラスを用意したとき、 kvconfig.messsage を設定しないといけませんが、Key Vault では「ドット」を使用できなので、kvconfig-message で代用します。

@Configuration
@ConfigurationProperties("kvconfig")
public class KvConfig {

    private String message;

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

シークレットの作成を選んで、hirakegema という値を定義しておきます。

image.png

次にこの Key Vault へのアクセス許可を設定します。「アクセスポリシ-」を開きポリシーを追加します。キー、シークレット、証明書に対して、それぞれ CRUD + List のような権限設定ができます。ここでは、シークレットの読込み権限が必要ですので、読み取りと一覧を付与します(一覧へのアクセス権限がないと失敗するのでご注意)。権限の付与は最低にし無駄に編集権限とかを与えるのはやめましょう。

image.png

プリンシパルの選択は、WebAppsの名前を指定すると、同名のサービスプリンシパルが指定できるでしょう。

image.png

Spring Boot アプリの設定

依存に、azure-spring-boot-starter-keyvault-secrets を設定します。

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>azure-spring-boot-starter-keyvault-secrets</artifactId>
    </dependency>

application.properties には、以下の情報が必要です。

  • テナントID
  • Key Vault のURL
  • クライアントID(Web Apps で Managed IDをオンにしたときに表示されるGUID)
azure.keyvault.enabled=true
azure.keyvault.client-id=ManagedIDのオブジェクトID
azure.keyvault.tenant-id=Azure AD のテナントID
azure.keyvault.uri=https://xxxxxxx.vault.azure.net/

コントローラークラスは、構成クラスをDIして表示するだけです。

 @RestController
public class KvController {

    private KvConfig config;

    public KvController(KvConfig config) {
        this.config = config;
    }

    @GetMapping("kv")
    public String getMessage() {
        return config.getMessage();
    }
}

デプロイ

デプロイしたエンドポイントに curl で APIを叩いてみましょう。 hirakegoma が表示されていれば正しく動作しています。これで Key Vault にアクセスするために、キーを管理する必要がなくなりました。

$ curl https://config-sample-1620013095057.azurewebsites.net/kv
hirakegoma

うまく動かない場合

うまく動かない場合は、だいたい設定に失敗して、Spring Boot 起動時に例外が発生していることが多いです。私も何度かやりました。そのような場合は、App Service から 「問題の診断と解決」というメニューを開いて、Application Log を参照すると、起動時の例外を見ることが出来るので、参考にしてください。

以下失敗例。

image.png

ローカル環境で試したい場合

.NET ですと、Visual Studio 自身が認証した情報をつかって Key Vault へアクセスしてくれるのですが、Javaのこのシナリオの場合は、Azure CLI の認証情報とかを勝手に使ってくれません。

このような場合は、手動でサービスプリンシパルを作成し、Key Vault のアクセス件を設定する必要があります。Azure CLI ですと以下のコマンドで作成できます。作成したサービスプリンシパルは、前述したKey Vault の設定でアクセス権を設定できます。

az ad sp create-for-rbac --name xxxxxxxxx

コマンドを実行すると、アプリケーションID(クラインとID)と、パスワードが表示されるので、それぞれ、client-idclient-key に設定します。

azure.keyvault.enabled=true
azure.keyvault.client-id=ManagedIDのオブジェクトID
azure.keyvault.tenant-id=Azure AD のテナントID
azure.keyvault.uri=https://xxxxxxx.vault.azure.net/
azure.keyvault.client-key=パスワード

これでローカル実行出来ると思います。

まとめ

今回は、先にWebAppsにデプロイした例を説明しましたが、ローカル環境からやったほうが簡単だと思います。意外とくだらない設定ミスで時間を潰したりするので、例外メッセージはきちんと読みましょう(>自分)

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?