Christian
Christian

Reputation: 904

Get certificates from Azure KeyVault to Keystore in Kotlin/SpringBoot for outgoing requests

For some API requests I need in my backend a certificate. Currently the .p12 is versioned in the repository and loaded into the WebClient when its initialized like this:

private fun getWebClient(): WebClient {
        val ks: KeyStore = KeyStore.getInstance("PKCS12")
        ks.load(ClassPathResource("keystore.p12").inputStream, config.trustStorePassword.toCharArray())
        val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
        kmf.init(ks, config.trustStorePassword.toCharArray())

        val sslContext = SslContextBuilder
            .forClient()
            .keyManager(kmf)
            .build()

        val httpClient: HttpClient = HttpClient.create().secure { sslSpec -> sslSpec.sslContext(sslContext) }

        return WebClient
            .builder()
            .baseUrl(config.BaseUrl)
            .clientConnector(ReactorClientHttpConnector(httpClient))
            .build()
    }

I want to change it since the backend is deployed to Azure AppService. I already created a KeyVault and imported the certificate and granted access via a managed identity to the AppService.

I currently struggle to load the keystore in Spring Boot from the KeyVault. For reference I am trying to follow https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-key-vault-certificates.

It uses the azure.keyvault.uri property which is apparently deprecated, so I am using spring.cloud.azure.keyvault.certificate.endpoint.

Also documentation states:

KeyStore azureKeyVaultKeyStore = KeyStore.getInstance("AzureKeyVault");
        KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter(
            System.getProperty("azure.keyvault.uri"));
        azureKeyVaultKeyStore.load(parameter);
        SSLContext sslContext = SSLContexts.custom()
                                           .loadTrustMaterial(azureKeyVaultKeyStore, null)
                                           .build();

However, I am not able to resolve the class KeyVautLoadStoreParameter.

I am using spring boot 2.7.7 and

implementation("com.azure.spring:spring-cloud-azure-starter:4.5.0")
implementation("com.azure.spring:spring-cloud-azure-starter-keyvault:4.5.0")

Any help towards loading the certificates and configuring the WebClient would be greatly appreciated.

Upvotes: 2

Views: 956

Answers (1)

Mohit Ganorkar
Mohit Ganorkar

Reputation: 2069

  • What you can do is create an app registration in azure AD and then grant access to this app registration through access policy in the azure keyvault.

  • Now collect the clientId , Tenant Id and client Secret from the app registration enter image description here

  • Create the secret in certificates&secret tab and click on new registration. enter image description here

  • Now create the application.yaml file in the following format

  
server:  
  ssl:  
    key-alias: TestCertificate  
    key-store-type: AzureKeyVault  
    trust-store-type: AzureKeyVault  
  port: 8443  
azure:  
  keyvault:  
    uri: <KEYVAULT URL> 
    client-id: <CLIENT_ID FROM APP REGISTRATIOM>  
    client-secret: <CLIENT_SECRET FROM APP REGISTRATIOM> 
    enabled: true  
    tenant-id: <TENANT_ID FROM APP REGISTRATIOM> 
  • Now you can import all the credentials from the azure key vault using the following program.
KeyStore azureKeyVaultKeyStore = KeyStore.getInstance("AzureKeyVault");

KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter(
    System.getProperty("azure.keyvault.uri"),  
    System.getProperty("azure.keyvault.tenant-id"),  
    System.getProperty("azure.keyvault.client-id"),  
    System.getProperty("azure.keyvault.client-secret")
);
azureKeyVaultKeyStore.load(parameter);
SSLContext sslContext = SSLContexts.custom()
    .loadTrustMaterial(azureKeyVaultKeyStore, null)
    .build();

// Here I am cross check wether we have imported the certificate name " TestCertificate"

if(azureKeyVaultKeyStore.containsAlias("TestCertificate"))  
{  
   System.out.println("The Certificate Exists ");  
}  
else {  
   System.out.println("Error Has Occured");  
}

Output: enter image description here

Upvotes: 1

Related Questions