Skip to content

Commit

Permalink
simplify certificate sample setup steps (#21856)
Browse files Browse the repository at this point in the history
* simplify certificate sample setup cost
  • Loading branch information
yiliuTo authored May 31, 2021
1 parent 78ef47e commit 387e742
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
<!-- embedme ../azure-spring-boot-samples/azure-spring-boot-sample-keyvault-certificates-client-side/src/main/java/com/azure/spring/security/keyvault/certificates/sample/client/side/SampleApplicationConfiguration.java#L72-L77 -->
```java
Expand All @@ -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
<!-- embedme ../../azure-spring-boot/src/samples/java/com/azure/spring/keyvault/KeyVaultJcaManagedIdentitySample.java#L18-L36 -->
```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
<!-- embedme ../../azure-spring-boot/src/samples/java/com/azure/spring/keyvault/KeyVaultJcaManagedIdentitySample.java#L42-L61 -->
```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
Expand All @@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,72 +11,103 @@ 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
```text
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

<!-- LINKS -->
Expand Down
Original file line number Diff line number Diff line change
@@ -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=
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

export KEY_VAULT_URI=

export SERVICE_PRINCIPAL_ID=

export SERVICE_PRINCIPAL_SECRET=

export SERVICE_PRINCIPAL_TETANT=
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 387e742

Please sign in to comment.