How to access secrets in Azure Key Vault using Java

What is Azure Key Vault?

Azure Key Vault is a cloud service offered by Microsoft to securely store cryptographic keys, certificates, and secrets. At StratoGator we use Key Vault as part of our solution to keep our client secrets secure.

How do I get started

The following information is required to access the Key Vault:

  • Key Vault URL
  • Client Id
  • Client Key (or certificate)

Key Vault URL

Create the Key Vault through the Azure Portal. The name you choose for the key vault will determine the first part of the URL:

https://your_key_vault_name.vault.azure.net

Client Id

To locate your client/application id:

  1. Navigate to Azure Active Directory.
  2. Select “App Registrations”.
  3. Choose your application.
  4. The Application ID can be copied from the page that appears.

Client Key

To generate a client/application key:

  1. Navigate to Azure Active Directory.
  2. Select “App Registrations”.
  3. Choose your application.
  4. Select the “Keys” blade.
  5. Add a new key and hit “Save”.
    1. When you create your new key, the secret value will be revealed. This is your only opportunity to copy the key value.

Permissions

In order for your application to have access to the Key Vault contents, you must set the appropriate permissions for your application in the Key Vault.

  1. Navigate to Key vaults.
  2. Select your Key Vault.
  3. Select the “Access Policies” blade.
  4. Select “Add new”.
    1. Choose your application as the Principal.
    2. Select the minimum required permissions for your application.
    3. Hit “OK” to complete.
  5. Select “Save” to save your new access policy.

Dependencies

Accessing an Azure Key Vault using Java requires the Azure SDK for Java (Maven link). and Azure KeyVault SDK for Java (Maven link).

These dependencies must be added to your pom.xml:

1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure</artifactId>
    <version>1.3.0</version>
</dependency>
<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-keyvault</artifactId>
    <version>1.0.0</version>
</dependency>

Connection

You must implement a KeyVaultCredentials class to connect to the Key Vault. The follow is an example adapted from the Microsoft KeyVaultCredentials API documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.example.azure.keyvault;

import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;
import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Based on example from Microsoft documentation:
 * https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/keyvault/authentication/KeyVaultCredentials.html
 */

public class ClientSecretKeyVaultCredential extends KeyVaultCredentials
{
    private String clientId;
    private String clientKey;

    public ClientSecretKeyVaultCredential( String clientId, String clientKey ) {
        this.clientId = clientId;
        this.clientKey = clientKey;
    }

    @Override
    public String doAuthenticate(String authorization, String resource, String scope) {
        AuthenticationResult token = getAccessTokenFromClientCredentials(
                authorization, resource, clientId, clientKey);
        return token.getAccessToken();
    }

    private static AuthenticationResult getAccessTokenFromClientCredentials(
            String authorization, String resource, String clientId, String clientKey) {
        AuthenticationContext context = null;
        AuthenticationResult result = null;
        ExecutorService service = null;
        try {
            service = Executors.newFixedThreadPool(1);
            context = new AuthenticationContext(authorization, false, service);
            ClientCredential credentials = new ClientCredential(clientId, clientKey);
            Future<AuthenticationResult> future = context.acquireToken(
                    resource, credentials, null);
            result = future.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            service.shutdown();
        }

        if (result == null) {
            throw new RuntimeException("authentication result was null");
        }
        return result;
    }
}

Access Key Vault information

Use the KeyVaultCredentials class you’ve created to instantiate a KeyVaultClient, and then perform your actions.

KeyVaultClient API documentation

For example:

1
2
3
4
5
6
7
8
// ClientSecretKeyVaultCredential is the implementation of KeyVaultCredentials
KeyVaultClient client = new KeyVaultClient(
        new ClientSecretKeyVaultCredential(clientId, clientKey));

// KEYVAULT_URL is the location of the keyvault to use: https://yourkeyvault.vault.azure.net
// "testSecret" is the name of the secret in the key vault
SecretBundle secret = client.getSecret( KEYVAULT_URL, "testSecret" );
log( secret.value() );

Related Links

How to use keys, secrets and certificates with Key Vault

Spring Boot Starter

By | 2017-10-20T23:00:13+00:00 October 20th, 2017|Technology|