From 04cd542829b0a175182e9d7e8e642b8db9f7a6d5 Mon Sep 17 00:00:00 2001 From: Moary Chen Date: Wed, 19 Aug 2026 11:19:23 +0800 Subject: [PATCH] Support disabling Key Vault JCA AIA downloads in Spring --- sdk/spring/CHANGELOG.md | 1 + .../jca/AzureKeyVaultSslBundleRegistrar.java | 4 +++ .../AzureKeyVaultSslBundleProperties.java | 12 +++++++ ...zureKeyVaultJcaAutoConfigurationTests.java | 3 ++ .../AzureKeyVaultSslBundleRegistrarTests.java | 34 +++++++++++++++++++ 5 files changed, 54 insertions(+) diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 333eed2d8dcc..b991dda0c06f 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -6,6 +6,7 @@ #### Features Added - Added `spring.ssl.bundle.keyvault..keystore.certificate-alias-filter-patterns` and `spring.ssl.bundle.keyvault..truststore.certificate-alias-filter-patterns` configuration. The patterns are passed to the Key Vault JCA provider to limit which certificate aliases are loaded. ([#50013](https://github.com/Azure/azure-sdk-for-java/issues/50013)) +- Added `spring.ssl.bundle.keyvault..keystore.disable-aia-download` and `spring.ssl.bundle.keyvault..truststore.disable-aia-download` configuration to disable automatic Authority Information Access (AIA) certificate downloads. The default is `false`. ([#50163](https://github.com/Azure/azure-sdk-for-java/pull/50163)) #### Bugs Fixed diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrar.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrar.java index 94ad331ebfce..92376f59c075 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrar.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrar.java @@ -46,6 +46,7 @@ public class AzureKeyVaultSslBundleRegistrar implements SslBundleRegistrar, Reso private final Map sslBundles; private static final String CERTIFICATE_ALIAS_FILTER_PATTERN_PROPERTY = "azure.keyvault.jca.certificate-alias-filter-pattern"; + private static final String DISABLE_AIA_DOWNLOAD_PROPERTY = "azure.keyvault.jca.disable-aia-download"; private static final String[] JCA_SYSTEM_PROPERTY_KEYS = new String[]{ "azure.keyvault.uri", "azure.keyvault.tenant-id", @@ -54,6 +55,7 @@ public class AzureKeyVaultSslBundleRegistrar implements SslBundleRegistrar, Reso "azure.keyvault.managed-identity", "azure.keyvault.jca.certificates-refresh-interval", CERTIFICATE_ALIAS_FILTER_PATTERN_PROPERTY, + DISABLE_AIA_DOWNLOAD_PROPERTY, "azure.keyvault.jca.refresh-certificates-when-have-un-trust-certificate", "azure.cert-path.well-known", "azure.cert-path.custom" @@ -221,6 +223,8 @@ private static void configureJcaKeyStoreSystemProperties(AzureKeyVaultJcaPropert }); pm.from(keyStoreProperties.isRefreshCertificatesWhenHaveUntrustedCertificate()) .to(v -> System.setProperty("azure.keyvault.jca.refresh-certificates-when-have-un-trust-certificate", Boolean.toString(v))); + pm.from(keyStoreProperties.isDisableAiaDownload()) + .to(v -> System.setProperty(DISABLE_AIA_DOWNLOAD_PROPERTY, Boolean.toString(v))); pm.from(keyStoreProperties.getCertificatePaths().getWellKnown()) .to(v -> resolvePath(resourceLoader, v).ifPresent(path -> System.setProperty("azure.cert-path.well-known", path))); diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/properties/AzureKeyVaultSslBundleProperties.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/properties/AzureKeyVaultSslBundleProperties.java index e61c3a2e9cd5..143bc1c6f6e1 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/properties/AzureKeyVaultSslBundleProperties.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/properties/AzureKeyVaultSslBundleProperties.java @@ -74,6 +74,10 @@ public static class KeyStoreProperties { * Whether to enable refresh certificate when get untrusted certificate. */ private boolean refreshCertificatesWhenHaveUntrustedCertificate; + /** + * Whether to disable automatic Authority Information Access (AIA) certificate chain completion downloads. + */ + private boolean disableAiaDownload; /** * Time interval to refresh all Key Vault certificate. */ @@ -104,6 +108,14 @@ public void setRefreshCertificatesWhenHaveUntrustedCertificate(boolean refreshCe this.refreshCertificatesWhenHaveUntrustedCertificate = refreshCertificatesWhenHaveUntrustedCertificate; } + public boolean isDisableAiaDownload() { + return disableAiaDownload; + } + + public void setDisableAiaDownload(boolean disableAiaDownload) { + this.disableAiaDownload = disableAiaDownload; + } + public Duration getCertificatesRefreshInterval() { return certificatesRefreshInterval; } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultJcaAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultJcaAutoConfigurationTests.java index bb26939cac1c..df5ac9c4649b 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultJcaAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultJcaAutoConfigurationTests.java @@ -52,6 +52,7 @@ void keyVaultJca() { "spring.cloud.azure.keyvault.jca.vaults.kv2.endpoint=" + String.format(ENDPOINT, "test2"), "spring.ssl.bundle.keyvault.testBundle1.truststore.certificate-paths.custom=classpath:keyvault/certificate-paths/custom", "spring.ssl.bundle.keyvault.testBundle2.truststore.keyvault-ref=kv2", + "spring.ssl.bundle.keyvault.testBundle2.truststore.disable-aia-download=true", "spring.ssl.bundle.keyvault.testBundle2.truststore.certificate-alias-filter-patterns[0]=^prod-.*", "spring.ssl.bundle.keyvault.testBundle2.truststore.certificate-alias-filter-patterns[1]=!^prod-deprecated$", "spring.ssl.bundle.keyvault.testBundle3.truststore.keyvault-ref=kv1", @@ -75,10 +76,12 @@ void keyVaultJca() { assertThat(sslBundlesProperties.getKeyvault()).hasSize(3); assertThat(sslBundlesProperties.getKeyvault().get("testBundle1").getTruststore().getCertificatePaths().getCustom()).isEqualTo("classpath:keyvault/certificate-paths/custom"); assertThat(sslBundlesProperties.getKeyvault().get("testBundle2").getTruststore().getKeyvaultRef()).isEqualTo("kv2"); + assertThat(sslBundlesProperties.getKeyvault().get("testBundle2").getTruststore().isDisableAiaDownload()).isTrue(); assertThat(sslBundlesProperties.getKeyvault().get("testBundle2").getTruststore() .getCertificateAliasFilterPatterns()).containsExactly("^prod-.*", "!^prod-deprecated$"); assertThat(sslBundlesProperties.getKeyvault().get("testBundle3").getTruststore().getKeyvaultRef()).isEqualTo("kv1"); assertThat(sslBundlesProperties.getKeyvault().get("testBundle3").getKeystore().getKeyvaultRef()).isEqualTo("kv2"); + assertThat(sslBundlesProperties.getKeyvault().get("testBundle3").getKeystore().isDisableAiaDownload()).isFalse(); assertThat(sslBundlesProperties.getKeyvault().get("testBundle3").getKeystore() .getCertificateAliasFilterPatterns()).containsExactly("client-cert", "!old-client-cert"); }); diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrarTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrarTests.java index 664f746f8dfb..25389965d9f4 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrarTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/keyvault/jca/AzureKeyVaultSslBundleRegistrarTests.java @@ -266,6 +266,40 @@ void configureCertificateAliasFilterPatterns() { } } + @Test + void configureDisableAiaDownload() { + AzureKeyVaultJcaProperties jcaProperties = new AzureKeyVaultJcaProperties(); + AzureKeyVaultSslBundleProperties sslBundleProperties = new AzureKeyVaultSslBundleProperties(); + AzureKeyVaultSslBundleRegistrar registrar = new AzureKeyVaultSslBundleRegistrar(jcaProperties, sslBundleProperties); + registrar.setResourceLoader(new DefaultResourceLoader()); + + try (MockedStatic keyStoreMockedStatic = mockStatic(KeyStore.class)) { + KeyStore keyStore = Mockito.mock(KeyStore.class); + List configuredValues = new ArrayList<>(); + keyStoreMockedStatic.when(() -> KeyStore.getInstance(KeyVaultJcaProvider.PROVIDER_NAME)) + .thenAnswer(invocation -> { + configuredValues.add(System.getProperty("azure.keyvault.jca.disable-aia-download")); + return keyStore; + }); + + AzureKeyVaultJcaProperties.JcaVaultProperties vaultProperties + = new AzureKeyVaultJcaProperties.JcaVaultProperties(); + vaultProperties.setEndpoint("https://test.vault.azure.net/"); + jcaProperties.getVaults().put("keyvault1", vaultProperties); + + AzureKeyVaultSslBundleProperties.KeyVaultSslBundleProperties bundleProperties + = new AzureKeyVaultSslBundleProperties.KeyVaultSslBundleProperties(); + bundleProperties.getKeystore().setKeyvaultRef("keyvault1"); + bundleProperties.getKeystore().setDisableAiaDownload(true); + bundleProperties.getTruststore().setKeyvaultRef("keyvault1"); + sslBundleProperties.getKeyvault().put("testBundle", bundleProperties); + + registrar.registerBundles(Mockito.mock(SslBundleRegistry.class)); + + assertThat(configuredValues).containsExactly("true", "false"); + } + } + @Test void keyVaultProviderNotInsertedAtHighestPriority() { AzureKeyVaultJcaProperties jcaProperties = new AzureKeyVaultJcaProperties();