From 387e7424e53e4b13dc0e5004029d724bd819da04 Mon Sep 17 00:00:00 2001 From: Yi Liu Date: Mon, 31 May 2021 14:52:12 +0800 Subject: [PATCH] simplify certificate sample setup steps (#21856) * simplify certificate sample setup cost --- .../README.md | 128 ++++++++++++++---- .../script/setup.sh | 4 + .../src/main/resources/application.yml | 8 +- .../README.md | 115 ++++++++++------ .../script/export_environment_variables.sh | 19 +++ ...vironment_variables_of_created_resource.sh | 9 ++ .../script/setup.sh | 40 ++++++ .../src/main/resources/application.yml | 10 +- .../README.md | 4 +- .../KeyVaultJcaManagedIdentitySample.java | 34 ++++- 10 files changed, 288 insertions(+), 83 deletions(-) create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/script/setup.sh create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables.sh create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables_of_created_resource.sh create mode 100644 sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/setup.sh diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/README.md b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/README.md index 1a49237f9e26e..948af03b5dbeb 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/README.md +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/README.md @@ -9,31 +9,26 @@ This sample should work together with [azure-spring-boot-sample-keyvault-certifi ### Prerequisites - [Environment checklist][environment_checklist] +- Start azure-spring-boot-sample-keyvault-certificates-server-side's SampleApplication. -### Config the sample -Fulfill these properties in application.yml: -```yaml -azure: - keyvault: - uri: # The URI to the Azure Key Vault used - tenant-id: # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). - client-id: # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). - client-secret: # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). -``` - -### How to run - -#### Run with TLS -1. Start azure-spring-boot-sample-keyvault-certificates-server-side's SampleApplication -1. Start azure-spring-boot-sample-keyvault-certificates-client-side's SampleApplication +### Run sample with service principal +1. Set environment variables created in `azure-spring-boot-sample-keyvault-certificates-server-side` application by running command: + ``` + source script/setup.sh + ``` +#### Using TLS with service principal +1. Start azure-spring-boot-sample-keyvault-certificates-client-side's SampleApplication by running command: + ``` + mvn spring-boot:run + ``` 1. Access http://localhost:8080/tls -Then you will get -```text -Response from "https://localhost:8443/": Hello World -``` + Then you will get + ```text + Response from "https://localhost:8443/": Hello World + ``` -#### Run with MTLS +#### Using mTLS with service principal 1. In the sample `ApplicationConfiguration.class`, change the `self-signed` to your certificate alias. ```java @@ -44,15 +39,91 @@ Response from "https://localhost:8443/": Hello World } } ``` -1. Start azure-spring-boot-sample-keyvault-certificates-server-side's SampleApplication -1. Start azure-spring-boot-sample-keyvault-certificates-client-side's SampleApplication with [MTLS] configuration. -1. When the [MTLS] server starts, `tls endpoint`(http://localhost:8080/tls) will not be able to access the resource. Access http://localhost:8080/mtls +1. Add properties in application.yml of `server side` on the base of current configuration: + ```yaml + server: + ssl: + client-auth: need # Used for mTLS + trust-store-type: AzureKeyVault # Used for mTLS + ``` +1. Start azure-spring-boot-sample-keyvault-certificates-client-side's SampleApplication by running command: + ``` + mvn spring-boot:run + ``` +1. When the mTLS server starts, `tls endpoint`(http://localhost:8080/tls) will not be able to access the resource. Access http://localhost:8080/mTLS -Then you will get -```text -Response from "https://localhost:8443/": Hello World -``` + Then you will get + ```text + Response from "https://localhost:8443/": Hello World + ``` +### Run sample with managed identity +1. If you are using managed identity instead of service principal, use below properties in your `application.yml`: + + ```yaml + azure: + keyvault: + uri: ${KEY_VAULT_URI} + managed-identity: # client-id of the user-assigned managed identity to use. If empty, then system-assigned managed identity will be used. + ``` + Make sure the managed identity can access target Key Vault. +1. Set environment variables created in `azure-spring-boot-sample-keyvault-certificates-server-side` application by running command: + ``` + source script/setup.sh + ``` + +#### Using TLS with managed identity +1. Replace the `restTemplateWithTLS` bean in `SampleApplicationConfiguration.java` as + + ```java + @Bean + public RestTemplate restTemplateWithTLS() throws Exception { + KeyStore trustStore = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.keyvault.managed-identity")); + trustStore.load(parameter); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(trustStore, null) + .build(); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, + (hostname, session) -> true); + CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(socketFactory) + .build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + + return new RestTemplate(requestFactory); + } + ``` +1. Follow the above step of [Using TLS with service principal](#using-tls-with-service-principal). + +#### Using mTLS with managed identity +1. Replace the `restTemplateWithMTLS` bean in `SampleApplicationConfiguration.java` as + + ```java + @Bean + public RestTemplate restTemplateWithMTLS() throws Exception { + KeyStore azureKeyVaultKeyStore = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.keyvault.managed-identity")); + azureKeyVaultKeyStore.load(parameter); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(azureKeyVaultKeyStore, null) + .loadKeyMaterial(azureKeyVaultKeyStore, "".toCharArray(), new ClientPrivateKeyStrategy()) + .build(); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, + (hostname, session) -> true); + CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(socketFactory) + .build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + + return new RestTemplate(requestFactory); + } + ``` +1. Follow the above step of [Using mTLS with service principal](#using-mtls-with-service-principal). ## Examples ## Troubleshooting @@ -64,4 +135,3 @@ Response from "https://localhost:8443/": Hello World [azure_spring_boot_starter_key_vault_certificates]: https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md [steps_to_store_certificate]: https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md#creating-an-azure-key-vault [azure-spring-boot-sample-keyvault-certificates-server-side]: https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side -[MTLS]: https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/README.md#run-with-MTLS diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/script/setup.sh b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/script/setup.sh new file mode 100644 index 0000000000000..391f4bf996b8a --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/script/setup.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +source ../azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables.sh +source ../azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables_of_created_resource.sh diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/src/main/resources/application.yml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/src/main/resources/application.yml index 176e9d83ce384..a176a930e0321 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/src/main/resources/application.yml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/src/main/resources/application.yml @@ -1,9 +1,9 @@ azure: keyvault: - uri: # The URI to the Azure Key Vault used - tenant-id: # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). - client-id: # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). - client-secret: # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). + uri: ${KEY_VAULT_URI} # The URI to the Azure Key Vault used + tenant-id: ${SERVICE_PRINCIPAL_TETANT} # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). + client-id: ${SERVICE_PRINCIPAL_ID} # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). + client-secret: ${SERVICE_PRINCIPAL_SECRET} # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). # managed-identity: # client-id of the user-assigned managed identity to use. # If the above 4 properties are empty, then system-assigned managed identity will be used. server: diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/README.md b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/README.md index d75ff01adbbdb..5269cce850360 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/README.md +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/README.md @@ -11,30 +11,38 @@ This sample can work together with [azure-spring-boot-sample-keyvault-certificat ### Prerequisites - [Environment checklist][environment_checklist] +- This sample will create a resource group and Azure Key Vault in your specified subscription. +- This sample will create and store a certificate in your Azure Key Vault. +- This sample will create a service principal to read certificates/keys/secrets from your Azure Key Vault. -### Store Certificate -We need to store certificate `self-signed` into Azure Key Vault with the following steps: [store certificate ][steps_to_store_certificate] - -### Config the sample -Fulfill these properties in application.yml: -```yaml -azure: - keyvault: - uri: # The URI to the Azure Key Vault used - tenant-id: # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). - client-id: # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). - client-secret: # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). -server: - port: 8443 - ssl: - key-alias: # The alias corresponding to the certificate in Azure Key Vault. - key-store-type: # The keystore type that enables the use of Azure Key Vault for your server-side SSL certificate. -``` - -### How to run - -#### Run with TLS -1. Start SampleApplication +### Run Sample with service principal +1. Run command `az login` to login to the Azure CLI. +1. Open `scripts/export_environment_variables.sh` and enter the following information: + ``` + # Set your Azure Subscription id where all required resources will be created. + export SUBSCRIPTION_ID= + + # Set the name for your Azure resource group to be created. + export RESOURCE_GROUP_NAME= + + # Set the region for all resources to be created. + export REGION_NAME= + + # Set the name for your Azure Key Vault to be created. + export KEY_VAULT_NAME= + + # Set the name for your certificate to be created. + export CERTIFICATE_NAME= + + # Set the name for your Service Principal to be created. It should be NULL if using managed identity. ==== + export SERVICE_PRINCIPAL_NAME= + ``` +1. Build up required Azure resources by running command. + ``` + source script/setup.sh + ``` +#### Using TLS with service principal +1. Run command `mvn spring-boot:run` 1. Access https://localhost:8443/ Then you will get @@ -42,41 +50,64 @@ Then you will get Hello World ``` -#### Run with MTLS +#### Using mTLS with service principal -1. Add properties in application.yml: +1. Add properties in application.yml on the base of current configuration: ```yaml -azure: - keyvault: - uri: # The URI to the Azure Key Vault used - tenant-id: # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). - client-id: # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). - client-secret: # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). server: - port: 8443 ssl: - key-alias: # The alias corresponding to the certificate in Azure Key Vault. - key-store-type: # The keystore type that enables the use of Azure Key Vault for your server-side SSL certificate. - client-auth: # Used for MTLS - trust-store-type: # Used for MTLS + client-auth: need # Used for mTLS + trust-store-type: AzureKeyVault # Used for mTLS ``` -1. Start SampleApplication -1. MTLS for mutual authentication. So your client needs have a trusted CA certificate.([azure-spring-boot-sample-keyvault-certificates-client-side]is a trusted client sample.) +2. Run command `mvn spring-boot:run` +1. mTLS for mutual authentication. So your client needs have a trusted CA certificate.([azure-spring-boot-sample-keyvault-certificates-client-side]is a trusted client sample.) 1. Your client access https://localhost:8443/ Then the client or server will get ```text Hello World ``` +### Run Sample with managed identity +If you are using managed identity instead of service principal, use below properties in your `application.yml`: + +```yaml +azure: + keyvault: + uri: ${KEY_VAULT_URI} +# managed-identity: # client-id of the user-assigned managed identity to use. If empty, then system-assigned managed identity will be used. +server: + ssl: + key-alias: self-signed + key-store-type: AzureKeyVault +``` +Make sure the managed identity can access target Key Vault. + +1. Run command `az login` to login to the Azure CLI. +1. Open `scripts/export_environment_variables.sh` and enter the following information: + ``` + # Set your Azure Subscription id where all required resources will be created. + export SUBSCRIPTION_ID= + + # Set the name for your Azure resource group to be created. + export RESOURCE_GROUP_NAME= + + # Set the region for all resources to be created. + export REGION_NAME= + + # Set the name for your Azure Key Vault to be created. + export KEY_VAULT_NAME= + ``` +1. Build up required Azure resources by running command + ``` + source script/setup.sh + ``` + +1. Follow the above step of [Using TLS with service principal](#using-tls-with-service-principal) or [Using mTLS with service principal](#using-mtls-with-service-principal). ## Examples ## Troubleshooting ## Next steps ## Run with Maven -``` -cd azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side -mvn spring-boot:run -``` ## Contributing diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables.sh b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables.sh new file mode 100644 index 0000000000000..9f1feb798fdc8 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Set your Azure Subscription id where all required resources will be created. +export SUBSCRIPTION_ID= + +# Set the name for your Azure resource group to be created. +export RESOURCE_GROUP_NAME= + +# Set the region for all resources to be created. +export REGION_NAME= + +# Set the name for your Azure Key Vault to be created. +export KEY_VAULT_NAME= + +# Set the name for your certificate to be created. +export CERTIFICATE_NAME= + +# Set the name for your Service Principal to be created. It should be NULL if using managed identity. ==== +export SERVICE_PRINCIPAL_NAME= diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables_of_created_resource.sh b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables_of_created_resource.sh new file mode 100644 index 0000000000000..ba17c62465e14 --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/export_environment_variables_of_created_resource.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +export KEY_VAULT_URI= + +export SERVICE_PRINCIPAL_ID= + +export SERVICE_PRINCIPAL_SECRET= + +export SERVICE_PRINCIPAL_TETANT= \ No newline at end of file diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/setup.sh b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/setup.sh new file mode 100644 index 0000000000000..748467b89b56c --- /dev/null +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/script/setup.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +source script/export_environment_variables.sh + +# ==== set Azure Subscription ==== +az account set --subscription ${SUBSCRIPTION_ID} + +# ==== Create Resource Group ==== +az group create --name ${RESOURCE_GROUP_NAME} --location ${REGION_NAME} + +# ==== Create Key Vault and certificate ==== +az keyvault create --name ${KEY_VAULT_NAME} \ + --resource-group ${RESOURCE_GROUP_NAME} \ + --location ${REGION_NAME} +KEY_VAULT_URI=$(az keyvault show --name ${KEY_VAULT_NAME} --resource-group ${RESOURCE_GROUP_NAME} | jq -r '.properties.vaultUri') +sed -i 's#export KEY_VAULT_URI=#&'"$KEY_VAULT_URI"'#' script/export_environment_variables_of_created_resource.sh + +az keyvault certificate create --vault-name ${KEY_VAULT_NAME} \ + -n ${CERTIFICATE_NAME} \ + -p "$(az keyvault certificate get-default-policy)" + +# ==== Create Service Principal ==== +if [ ${SERVICE_PRINCIPAL_NAME} ];then + SERVICE_PRINCIPAL_SECRET=$(az ad sp create-for-rbac --name ${SERVICE_PRINCIPAL_NAME} | jq -r '.password') + sed -i 's#export SERVICE_PRINCIPAL_SECRET=#&'"$SERVICE_PRINCIPAL_SECRET"'#' script/export_environment_variables_of_created_resource.sh + + SERVICE_PRINCIPAL_ID=$(az ad sp list --display-name ${SERVICE_PRINCIPAL_NAME} | jq -r '.[0].appId') + sed -i 's#export SERVICE_PRINCIPAL_ID=#&'"$SERVICE_PRINCIPAL_ID"'#' script/export_environment_variables_of_created_resource.sh + + SERVICE_PRINCIPAL_TETANT=$(az ad sp list --display-name ${SERVICE_PRINCIPAL_NAME} | jq -r '.[0].appOwnerTenantId') + sed -i 's#export SERVICE_PRINCIPAL_TETANT=#&'"$SERVICE_PRINCIPAL_TETANT"'#' script/export_environment_variables_of_created_resource.sh + + az keyvault set-policy --name ${KEY_VAULT_NAME} --certificate-permission get list \ + --key-permission get list \ + --secret-permission get list \ + --spn ${SERVICE_PRINCIPAL_ID} \ + --resource-group ${RESOURCE_GROUP_NAME} +fi + +source script/export_environment_variables_of_created_resource.sh diff --git a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/src/main/resources/application.yml b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/src/main/resources/application.yml index 9c202b1d38956..41464d877bc6a 100644 --- a/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/src/main/resources/application.yml +++ b/sdk/spring/azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-server-side/src/main/resources/application.yml @@ -1,15 +1,15 @@ azure: keyvault: - uri: # The URI to the Azure Key Vault used - tenant-id: # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). - client-id: # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). - client-secret: # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). + uri: ${KEY_VAULT_URI} # The URI to the Azure Key Vault used + tenant-id: ${SERVICE_PRINCIPAL_TETANT} # The Tenant ID for your Azure Key Vault (needed if you are not using managed identity). + client-id: ${SERVICE_PRINCIPAL_ID} # The Client ID that has been setup with access to your Azure Key Vault (needed if you are not using managed identity). + client-secret: ${SERVICE_PRINCIPAL_SECRET} # The Client Secret that will be used for accessing your Azure Key Vault (needed if you are not using managed identity). # managed-identity: # The user-assigned managed identity client-id to use. # If the above 4 properties are empty, then system-assigned managed identity will be used. server: port: 8443 ssl: - key-alias: # The alias corresponding to the certificate in Azure Key Vault. + key-alias: ${CERTIFICATE_NAME} # The alias corresponding to the certificate in Azure Key Vault. key-store-type: AzureKeyVault # The keystore type that enables the use of Azure Key Vault for your server-side SSL certificate. # client-auth: need # Used for MTLS # trust-store-type: AzureKeyVault # Used for MTLS diff --git a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md index a3e56729ab889..db2732a798b49 100644 --- a/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md +++ b/sdk/spring/azure-spring-boot-starter-keyvault-certificates/README.md @@ -208,10 +208,10 @@ Make sure the managed identity can access target Key Vault. Configure a `RestTemplate` bean which set the `AzureKeyVault` as trust store: - + ```java @Bean -public RestTemplate restTemplateCreatedByManagedIdentity() throws Exception { +public RestTemplate restTemplateWithTLS() throws Exception { KeyStore trustStore = KeyStore.getInstance("AzureKeyVault"); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/keyvault/KeyVaultJcaManagedIdentitySample.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/keyvault/KeyVaultJcaManagedIdentitySample.java index 023e9ac7eb2b5..667640c5d1bf6 100644 --- a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/keyvault/KeyVaultJcaManagedIdentitySample.java +++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/keyvault/KeyVaultJcaManagedIdentitySample.java @@ -6,17 +6,21 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.PrivateKeyDetails; +import org.apache.http.ssl.PrivateKeyStrategy; import org.apache.http.ssl.SSLContexts; import org.springframework.context.annotation.Bean; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; +import java.net.Socket; import java.security.KeyStore; +import java.util.Map; public class KeyVaultJcaManagedIdentitySample { @Bean - public RestTemplate restTemplateCreatedByManagedIdentity() throws Exception { + public RestTemplate restTemplateWithTLS() throws Exception { KeyStore trustStore = KeyStore.getInstance("AzureKeyVault"); KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( System.getProperty("azure.keyvault.uri"), @@ -34,4 +38,32 @@ public RestTemplate restTemplateCreatedByManagedIdentity() throws Exception { return new RestTemplate(requestFactory); } + + @Bean + public RestTemplate restTemplateWithMTLS() throws Exception { + KeyStore azureKeyVaultKeyStore = KeyStore.getInstance("AzureKeyVault"); + KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter( + System.getProperty("azure.keyvault.uri"), + System.getProperty("azure.keyvault.managed-identity")); + azureKeyVaultKeyStore.load(parameter); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(azureKeyVaultKeyStore, null) + .loadKeyMaterial(azureKeyVaultKeyStore, "".toCharArray(), new ClientPrivateKeyStrategy()) + .build(); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, + (hostname, session) -> true); + CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(socketFactory) + .build(); + HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + + return new RestTemplate(requestFactory); + } + + private static class ClientPrivateKeyStrategy implements PrivateKeyStrategy { + @Override + public String chooseAlias(Map map, Socket socket) { + return "self-signed"; // It should be your certificate alias used in client-side + } + } }