今回も引き続き、Key Vaultを作成しKey Vaultのシークレットを取得する処理の実装について述べる。ここでは、具体的なサンプルプログラムのソースコードを共有する。
前提条件
下記記事のKeyVaultの作成が完了していること。
作成したサンプルプログラム(App Service側)の内容
作成したサンプルプログラム(App Service側)の構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
pom.xmlの内容は以下の通りで、Key Vaultのライブラリの設定を追加している。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demoAzureApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demoAzureApp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombokの設定 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Key Vaultの設定 -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-secrets</artifactId>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure</artifactId>
<version>1.36.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>1.12.0</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<subscriptionId>(ログインユーザーのサブスクリプションID)</subscriptionId>
<resourceGroup>azureAppDemo</resourceGroup>
<appName>azureAppDemoService</appName>
<pricingTier>B1</pricingTier>
<region>japaneast</region>
<appServicePlanName>ASP-azureAppDemo-8679</appServicePlanName>
<appServicePlanResourceGroup>azureAppDemo</appServicePlanResourceGroup>
<runtime>
<os>Linux</os>
<javaVersion>Java 8</javaVersion>
<webContainer>Tomcat 8.5</webContainer>
</runtime>
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.war</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
</plugins>
</build>
</project>また、application.propertiesの内容は以下の通りで、サービスプリンシパルを利用してKey Vaultにアクセスするための設定を追加している。
server.port = 8084 demoAzureFunc.urlBase = http://localhost:7071/api/ #demoAzureFunc.urlBase = https://azurefuncdemoapp.azurewebsites.net/api/ # Key Vaultへの設定 keyVaultClientId=cdbb5434-e455-4885-b2e6-911f78c4264b keyVaultTenantId=f6a12dea-7649-441f-9e63-bc9e254b2500 keyVaultClientKey=(サービスプリンシパルのパスワード) keyVaultUri=https://keypurinit.vault.azure.net/ keyVaultSecretKey=keySecret
なお、上記設定のkeyVaultClientId、keyVaultTenantId、keyVaultClientKey、keyVaultUriは、以下のサービスプリンシパル作成時のコマンド実行時に出力されたappId、tenant、password、nameの値を指定している。

また、keyVaultSecretKeyは、以下の画面のシークレットのキー値を指定している。

コントローラクラスの内容は以下の通りで、後述するAzure Functions側のgetKeySecret関数を呼び出す処理と、KeyVaultからシークレットを取得する処理を追加している。
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.azure.AzureEnvironment;
import com.microsoft.azure.credentials.ApplicationTokenCredentials;
import com.microsoft.azure.keyvault.KeyVaultClient;
import com.microsoft.azure.keyvault.models.SecretBundle;
@Controller
public class DemoController {
/** RestTemplateオブジェクト */
@Autowired
private RestTemplate restTemplate;
/** ObjectMapperオブジェクト */
@Autowired
private ObjectMapper objectMapper;
/** application.propertiesからdemoAzureFunc.urlBaseの値を取得 */
@Value("${demoAzureFunc.urlBase}")
private String demoAzureFuncBase;
/** keyVaultのクライアントID */
@Value("${keyVaultClientId}")
private String keyVaultClientId;
/** keyVaultのテナントID */
@Value("${keyVaultTenantId}")
private String keyVaultTenantId;
/** keyVaultのクライアントキー */
@Value("${keyVaultClientKey}")
private String keyVaultClientKey;
/** keyVaultのURI */
@Value("${keyVaultUri}")
private String keyVaultUri;
/** keyVaultのシークレットのキー */
@Value("${keyVaultSecretKey}")
private String keyVaultSecretKey;
@GetMapping("/")
public String index(Model model) {
// Azure FunctionsのgetKeySecret関数を呼び出すためのヘッダー情報を設定する
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// Azure FunctionsのgetKeySecret関数を呼び出すための引数を設定する
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
try {
map.add("key", "keySecret");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
HttpEntity<MultiValueMap<String, String>> entity
= new HttpEntity<>(map, headers);
// Azure FunctionsのgetKeySecret関数を呼び出す
ResponseEntity<String> response = restTemplate.exchange(demoAzureFuncBase
+ "getKeySecret", HttpMethod.POST, entity, String.class);
// Azure Functionsの呼出結果のシークレットを、Modelオブジェクトに設定する
try {
GetKeySecretResult getKeySecretResult = objectMapper.readValue(
response.getBody(), GetKeySecretResult.class);
model.addAttribute("keySecretFunctions", getKeySecretResult.getSecret());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
// Azure App Serviceでのシークレットを、Modelオブジェクトに設定する
model.addAttribute("keySecretAppService", getKeySecret());
return "index";
}
/**
* KeyVaultからシークレットを取得する
*
* @return シークレット値
*/
private String getKeySecret() {
ApplicationTokenCredentials credentials
= new ApplicationTokenCredentials(keyVaultClientId
, keyVaultTenantId, keyVaultClientKey, AzureEnvironment.AZURE);
KeyVaultClient keyVaultClient = new KeyVaultClient(credentials);
SecretBundle bundle
= keyVaultClient.getSecret(keyVaultUri, keyVaultSecretKey);
return bundle.value();
}
}また、Azure Functions側のgetKeySecret関数を呼び出した結果を格納するクラスは、以下の通り。
package com.example.demo;
import lombok.Data;
@Data
public class GetKeySecretResult {
/** シークレットの値 */
private String secret;
}さらに、コンフィグクラスの内容は以下の通りで、コントローラクラスで呼び出すBean定義を行っている。
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
public class DemoConfigBean {
/**
* RestTemplateオブジェクトを作成する
* @return RestTemplateオブジェクト
*/
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
/**
* ObjectMapperオブジェクトを作成する
* @return ObjectMapperオブジェクト
*/
@Bean
public ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
}また、HTMLファイルの内容は以下の通りで、取得したシークレットの値を表示するようにしている。
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>初期表示画面</title>
</head>
<body>
Azure App Serviceで取得したシークレット:
<span th:text="${keySecretAppService}">keySecretAppService</span><br/><br/>
Azure Functionsで取得したシークレット:
<span th:text="${keySecretFunctions}">keySecretFunctions</span>
</body>
</html>その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/azure/tree/master/azure-key-vault-2/demoAzureApp
作成したサンプルプログラム(Azure Functions側)の内容
作成したサンプルプログラム(Azure Functions側)の構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
<2021年4月13日 追記>
spring-cloud-function-dependenciesのバージョンは、2021年3月16日にリリースしたバージョン3.1.2を利用すると、1つのAzure Functions内に複数のファンクションを含む場合の不具合が解消できている。
その場合、Handlerクラスの継承するクラスを「AzureSpringBootRequestHandler」クラスから「FunctionInvoker」クラスに変更する。
spring-cloud-function-dependenciesの3.1.2を利用した実装サンプルは、以下の記事を参照のこと。
pom.xmlの内容は以下の通りで、App Service側と同様に、Key Vaultのライブラリの設定を追加している。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demoAzureFunc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Hello Spring Function on Azure</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<azure.functions.maven.plugin.version>1.9.0</azure.functions.maven.plugin.version>
<!-- customize those properties. The functionAppName should be unique across Azure -->
<functionResourceGroup>azureAppDemo</functionResourceGroup>
<functionAppName>azureFuncDemoApp</functionAppName>
<functionAppServicePlan>ASP-azureAppDemo-8679</functionAppServicePlan>
<functionPricingTier>B1</functionPricingTier>
<functionAppRegion>japaneast</functionAppRegion>
<stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
<start-class>com.example.DemoAzureFunction</start-class>
<spring.boot.wrapper.version>1.0.25.RELEASE</spring.boot.wrapper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-azure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-function-web</artifactId>
<scope>provided</scope>
</dependency>
<!-- Spring Boot Webの設定 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombokを利用するための設定 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- Key Vaultの設定 -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-secrets</artifactId>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure</artifactId>
<version>1.36.3</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-dependencies</artifactId>
<version>2.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<version>${azure.functions.maven.plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-functions-maven-plugin</artifactId>
<configuration>
<resourceGroup>${functionResourceGroup}</resourceGroup>
<appName>${functionAppName}</appName>
<appServicePlanName>${functionAppServicePlan}</appServicePlanName>
<region>${functionAppRegion}</region>
<pricingTier>${functionPricingTier}</pricingTier>
<runtime>
<os>Linux</os>
<javaVersion>8</javaVersion>
</runtime>
<appSettings>
<!-- Run Azure Function from package file by default -->
<property>
<name>WEBSITE_RUN_FROM_PACKAGE</name>
<value>1</value>
</property>
<property>
<name>FUNCTIONS_EXTENSION_VERSION</name>
<value>~3</value>
</property>
<property>
<name>FUNCTIONS_WORKER_RUNTIME</name>
<value>java</value>
</property>
</appSettings>
</configuration>
<executions>
<execution>
<id>package-functions</id>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>
${project.build.directory}/azure-functions/${functionAppName}
</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/azure
</directory>
<includes>
<include>**</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${stagingDirectory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<!--Remove obj folder generated by .NET SDK in maven clean-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<filesets>
<fileset>
<directory>obj</directory>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${spring.boot.wrapper.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>application.propertiesの内容は以下の通りで、App Service側と同様に、サービスプリンシパルを利用してKey Vaultにアクセスするための設定を追加している。
# Key Vaultへの設定 keyVaultClientId=cdbb5434-e455-4885-b2e6-911f78c4264b keyVaultTenantId=f6a12dea-7649-441f-9e63-bc9e254b2500 keyVaultClientKey=(サービスプリンシパルのパスワード) keyVaultUri=https://keypurinit.vault.azure.net/ keyVaultSecretKey=keySecret
サービスクラスの内容は以下の通りで、App Service側と同様に、KeyVaultからシークレットを取得する処理を追加している。
package com.example.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.example.model.GetKeySecretForm;
import com.example.model.GetKeySecretResult;
import com.microsoft.azure.AzureEnvironment;
import com.microsoft.azure.credentials.ApplicationTokenCredentials;
import com.microsoft.azure.keyvault.KeyVaultClient;
import com.microsoft.azure.keyvault.models.SecretBundle;
@Service
public class GetKeySecretService {
/** keyVaultのクライアントID */
@Value("${keyVaultClientId}")
private String keyVaultClientId;
/** keyVaultのテナントID */
@Value("${keyVaultTenantId}")
private String keyVaultTenantId;
/** keyVaultのクライアントキー */
@Value("${keyVaultClientKey}")
private String keyVaultClientKey;
/** keyVaultのURI */
@Value("${keyVaultUri}")
private String keyVaultUri;
/** keyVaultのシークレットのキー */
@Value("${keyVaultSecretKey}")
private String keyVaultSecretKey;
/**
* 検索用Formに設定したキーにあてはまるシークレットを取得する
*
* @param getKeySecretForm 検索用Form
* @return 結果情報オブジェクト
*/
public GetKeySecretResult getKeySecret(GetKeySecretForm getKeySecretForm) {
GetKeySecretResult getKeySecretResult = new GetKeySecretResult();
if (keyVaultSecretKey.equals(getKeySecretForm.getKey())) {
// KeyVaultからシークレットを取得し設定する
getKeySecretResult.setSecret(getKeySecret());
}
return getKeySecretResult;
}
/**
* KeyVaultからシークレットを取得する
*
* @return シークレット値
*/
private String getKeySecret() {
ApplicationTokenCredentials credentials
= new ApplicationTokenCredentials(keyVaultClientId
, keyVaultTenantId, keyVaultClientKey, AzureEnvironment.AZURE);
KeyVaultClient keyVaultClient = new KeyVaultClient(credentials);
SecretBundle bundle
= keyVaultClient.getSecret(keyVaultUri, keyVaultSecretKey);
return bundle.value();
}
}ハンドラークラスの内容は以下の通りで、Azure App Serviceのコントローラクラスから呼ばれるgetKeySecret関数である。
package com.example;
import java.util.Optional;
import org.springframework.cloud.function.adapter.azure.AzureSpringBootRequestHandler;
import com.example.model.GetKeySecretForm;
import com.example.model.GetKeySecretResult;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
public class GetKeySecretHandler
extends AzureSpringBootRequestHandler<GetKeySecretForm, GetKeySecretResult> {
/**
* HTTP要求に応じて、DemoAzureFunctionクラスのgetKeySecretメソッドを呼び出し、
* その戻り値をボディに設定したレスポンスを返す
* @param request リクエストオブジェクト
* @param context コンテキストオブジェクト
* @return レスポンスオブジェクト
*/
@FunctionName("getKeySecret")
public HttpResponseMessage execute(
@HttpTrigger(name = "request"
, methods = HttpMethod.POST, authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
ExecutionContext context) {
// リクエストオブジェクトからパラメータ値を取得し、検索用Formに設定する
ObjectMapper mapper = new ObjectMapper();
String jsonParam = request.getBody().get();
jsonParam = jsonParam.replaceAll("\\[", "").replaceAll("\\]", "");
GetKeySecretForm getKeySecretForm = new GetKeySecretForm();
try {
getKeySecretForm = mapper.readValue(jsonParam
, new TypeReference<GetKeySecretForm>() {
});
} catch (Exception ex) {
throw new RuntimeException(ex);
}
// handleRequestメソッド内でDemoAzureFunctionクラスのgetKeySecretメソッド
// を呼び出し、その戻り値をボディに設定したレスポンスを、JSON形式で返す
return request.createResponseBuilder(HttpStatus.OK)
.body(handleRequest(getKeySecretForm, context))
.header("Content-Type", "text/json").build();
}
}また、Azure Functionsのメインクラスは以下の通りで、前述のサービスクラスを呼び出していて、先ほどのハンドラークラスのhandleRequestメソッドで呼び出される。
package com.example;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.example.model.GetKeySecretForm;
import com.example.model.GetKeySecretResult;
import com.example.service.GetKeySecretService;
@SpringBootApplication
public class DemoAzureFunction {
/** シークレット取得サービスクラスのオブジェクト */
@Autowired
private GetKeySecretService getKeySecretService;
public static void main(String[] args) throws Exception {
SpringApplication.run(DemoAzureFunction.class, args);
}
/**
* キーに対応するシークレットを取得し結果を返却する関数
*
* @return シークレット取得サービスクラスの呼出結果
*/
@Bean
public Function<GetKeySecretForm, GetKeySecretResult> getKeySecret() {
return getKeySecretForm
-> getKeySecretService.getKeySecret(getKeySecretForm);
}
}さらに、Azure FunctionsのメインクラスのgetKeySecretメソッドの引数・戻り値は以下のクラスで定義している。
package com.example.model;
import lombok.Data;
@Data
public class GetKeySecretForm {
/** キーの値 */
private String key;
}package com.example.model;
import lombok.Data;
@Data
public class GetKeySecretResult {
/** シークレットの値 */
private String secret;
}その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/azure/tree/master/azure-key-vault-2/demoAzureFunc
要点まとめ
- プログラム上でKeyVaultのシークレットを取得するには、pom.xmlにKey Vaultにアクセスするためのライブラリを追加し、application.propertiesにサービスプリンシパルの設定値を追加し、KeyVaultClientクラスを使ってシークレットの取得を行えばよい。

