简体   繁体   中英

Connect to Cosmos using key from Key Vault

I have a Spring Boot application which needs to make use of CosmosDB. My goal is to load the CosmosDB connection key from Key Vault and use that to connect to CosmosDB. I have placed the key as a secret in Key Vault, but it seems that there is an ordering issue going on, as the Cosmos bean is created before the Key Vault. I am able to connect to successfully connect to Key Vault and have received several keys before this, and I am also able to connect to Cosmos if I hard code the connection key. Is it possible to load the key from Key Vault and use it to create the Cosmos bean?

What I have tried is the following, but I receive a connection error with Cosmos (due to the key being not set) - probably because it loads before the Key Vault. Is there a robust way to connect to Cosmos or any proper examples available for Spring boot?

Dependencies I am using:

azure-cosmosdb-spring-boot-starter (from com.microsoft.azure)
azure-identity (from com.azure)
azure-security-keyvault-secrets (from com.azure)

CosmosConfiguration.java class:

@Slf4j
@Configuration
@Profile("!local")
public class CosmosConfiguration extends AbstractCosmosConfiguration {
    @Value("${cosmosPrimaryKey}")
    private String key;

    @Override
    public CosmosClient cosmosClient(CosmosDBConfig config) {
        return CosmosClient
            .builder()
            .endpoint(config.getUri())
            .cosmosKeyCredential(new CosmosKeyCredential(key))
            .consistencyLevel(consistencyLevel.STRONG)
            .build()
    }
} 

The application.properties (only the relevant parts):

azure.keyvault.enabled=true
azure.keyvault.uri=https://mykeyvault.azure.net
azure.keyvault.secrets-keys=cosmosPrimaryKey

cosmosdb.keyname=cosmosPrimaryKey

azure.cosmosdb.uri=https://mycosmos.documents.azure.com:443
azure.cosmodb.repositories.enabled=true

spring.main.allow-bean-definition-overriding=true

My idea on your case is add judgement when creating 'CosmosClient'. And here's my code.

@Autowired
private CosmosProperties properties;

public CosmosClientBuilder cosmosClientBuilder() {
            DirectConnectionConfig directConnectionConfig = DirectConnectionConfig.getDefaultConfig();
            String uri = properties.getUri();
            if(true) {
                String temp = getConnectUriFromKeyvault();
                properties.setUri(temp);
            }
            return new CosmosClientBuilder()
                .endpoint(properties.getUri())
                .key(properties.getKey())
                .directMode(directConnectionConfig);
        }

public String getConnectUriFromKeyvault() {
        SecretClient secretClient = new SecretClientBuilder()
                .vaultUrl("https://vauxxxxen.vault.azure.net/")
                .credential(new DefaultAzureCredentialBuilder().build())
                .buildClient();
        KeyVaultSecret secret = secretClient.getSecret("cosmosdbScanWithwrongkey");
        return secret.getValue();
    }

CosmosProperties entity:

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

@ConfigurationProperties(prefix = "cosmos")
public class CosmosProperties {

    private String uri;

    private String key;

    private String secondaryKey;

    private boolean queryMetricsEnabled;
    //get set function
    //...
}

application.properties:

cosmos.uri=https://txxxb.documents.azure.com:443/
cosmos.key=gdvBggxxxxxWA==
cosmos.secondaryKey=wDcxxxfinXg==
dynamic.collection.name=spel-property-collection
# Populate query metrics
cosmos.queryMetricsEnabled=true

I followed this doc to get key vault secret.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM