Java App Configuration Client returns Key Vault secret URI, not actual secret value

CareyBoldenow 96 Reputation points
2021-05-16T14:28:52.41+00:00

I have created a simple Spring Boot App Service in Azure to learn about the Azure App Configuration capabilities. This app uses both the "MessageProperties" approach that is used in the Azure Documentation (see code below) and also uses a com.azure.data.appconfiguration.ConfigurationClient implementation to get settings from my App Configuration resource using a client.

import org.springframework.boot.context.properties.ConfigurationProperties;  
import org.springframework.context.annotation.Configuration;  

@Configuration  
@ConfigurationProperties  
public class MessageProperties {  

    private String message;  

    private String myKeyVaultSecret;  

    public String getMessage() {  
        return message;  
    }  

    public void setMessage(String message) {  
        this.message = message;  
    }  

    public String getMyKeyVaultSecret() {  
        return myKeyVaultSecret;  
    }  

    public void setMyKeyVaultSecret(String myKeyVaultSecret) {  
        this.myKeyVaultSecret = myKeyVaultSecret;  
    }  
}  

For now, I am only use App Configuration to store two settings. One is just a simple name/value pair and the other is KeyVault reference (see below):

96962-image.png

I have done all the other related things that need to be done in order for my App Service to be able to get Key Vault secrets. I created a System Managed Identity for my App Service and created an Access Policy in Key Vault for this Managed Identity to get/list secrets. I also create a Role Assignment in my App Configuration Resource that grants the "App Configuration Data Reader" role to my App Service.

I then created a basic RestController that returns the two settings I created in App Configuration. However, the thing to note is that this controller returns the KeyVault referenced setting in two different ways. One using the "MessageProperties" based implementation and the other using the Java SDK ClientConfiguration based implementation. I have provided the code for my Controller below, which also includes the App Configuration Client code:

import com.azure.data.appconfiguration.ConfigurationClient;  
import com.azure.data.appconfiguration.ConfigurationClientBuilder;  
import com.azure.data.appconfiguration.models.ConfigurationSetting;  
import com.azure.identity.DefaultAzureCredential;  
import com.azure.identity.DefaultAzureCredentialBuilder;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  

import java.io.IOException;  

@RestController  
public class HelloController {  
    private final MessageProperties properties;  

    public HelloController(MessageProperties properties) {  
        this.properties = properties;  
    }  

    @GetMapping  
    public Response getMessage() {  
        Response response = new Response();  
        response.setMessage((properties.getMessage()));  
        response.setSecretFromProps(properties.getMyKeyVaultSecret());  
        response.setSecretFromClient(getPropertyFromClient());  
        return response;  
    }  

    private String getPropertyFromClient() {  

        DefaultAzureCredential tokenCredential = new DefaultAzureCredentialBuilder().build();  
        final ConfigurationClient client = new ConfigurationClientBuilder()  
                .credential(tokenCredential) // use Managed Identity  
                .endpoint("https://my-dev-app-configuration.azconfig.io")  
                .buildClient();  

        try {  
            ConfigurationSetting setting = client.getConfigurationSetting("/application/myKeyVaultSecret", null);  
            return setting.getValue();  
        } catch(Exception e) {  
            return "default";  
        }  

    }  
}  

When I deploy the code to my App Service in Azure and make a request to my API, the response I get is as follows (with some alteration to mask secrets):

{
"message": "Hello World!",
"secretFromProps": "Endpoint=sb://my-dev-eventhub.servicebus.windows.net...",
"secretFromClient": "{\"uri\":\"https://my-dev-key-vault.vault.azure.net/secrets/event-hub-connection\"}"
}

As you can see, my MessageProperties instance provided the actual value for the KeyVault secret reference I created in App Configuration. However, my App Configuration Client simply returns the KeyVault secret URI that I selected when I created the KeyVault reference in App Configuration. It's as though the client cannot distinguish between simple name/value pairs in App Configuration and KeyVault referenced settings. Is this the expected behavior or am I missing something? I have also provided the key dependencies I am using, as well as a copy of my bootstrap.properties file:

Dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>spring-cloud-azure-appconfiguration-config-web</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-data-appconfiguration</artifactId>
<version>1.1.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

bootstrap.properties
spring.cloud.azure.appconfiguration.stores[0].endpoint=${APP_CONFIGURATION_ENDPOINT}
spring.cloud.azure.appconfiguration.cache-expiration=10s

Thanks for any help you can provide!

Azure App Configuration
Azure App Configuration
An Azure service that provides hosted, universal storage for Azure app configurations.
215 questions
{count} votes

Accepted answer
  1. svijay-MSFT 5,226 Reputation points Microsoft Employee
    2021-05-19T15:15:46.233+00:00

    @CareyBoldenow

    I tested the behavior at my end & I was able to observe similar behavior at my end.

    Per my research, there is an implementation to automatically resolve it in .NET. Unfortunately, the Java SDK Config client doesn't have the implementation to resolve the actual value from the reference.

    In order to meet your goal, you will have to obtain the key-value, Parse the value for the secret identifier and then get the secret identifier using the getSecret()

    References :

    1. https://github.com/Azure/azure-sdk-for-js/issues/12910
    2. https://stackoverflow.com/questions/65919559/access-azure-app-configuration-settings-that-reference-key-vault-in-nodejs/66018270

    Additional Note :

    I also came accross the SecretReferenceConfigurationSetting in the beta version of the SDK . Unfortunately, there were no methods that is responsible for resolving it


0 additional answers

Sort by: Most helpful