11package com .example .evidence .config ;
22
3+ import com .azure .core .credential .TokenCredential ;
34import com .azure .identity .DefaultAzureCredentialBuilder ;
5+ import com .azure .identity .ManagedIdentityCredentialBuilder ;
46import com .azure .storage .file .datalake .DataLakeServiceClient ;
57import com .azure .storage .file .datalake .DataLakeServiceClientBuilder ;
68import org .springframework .beans .factory .annotation .Value ;
1012
1113/**
1214 * Builds a DataLakeServiceClient for ADLS Gen2 using a Managed Identity
13- * (or Azure CLI / dev credential) via DefaultAzureCredential . Shared keys
14- * are disabled on the target storage account; all auth flows through Entra
15- * ID + Storage Blob Data Contributor RBAC.
15+ * (or Azure CLI / dev credential). Shared keys are disabled on the target
16+ * storage account; all auth flows through Entra ID + Storage Blob Data
17+ * Contributor RBAC.
1618 *
1719 * The endpoint targets *.dfs.core.windows.net which, from inside the VNet,
1820 * resolves to the Private Endpoint NIC IP via the privatelink.dfs.* DNS
1921 * zone. From outside the VNet (e.g. local dev), the public DFS endpoint is
2022 * used and access is gated by the storage networkAcls.
23+ *
24+ * When running in App Service we pin to ManagedIdentityCredential to
25+ * avoid the DefaultAzureCredential chain falling back to a stale or wrong
26+ * principal (the chain has logged "EnvironmentCredential unavailable"
27+ * before failing over). The presence of the IDENTITY_ENDPOINT environment
28+ * variable is the standard signal that an MI endpoint is available.
2129 */
2230@ Configuration
2331@ Profile ("!dev" )
@@ -30,7 +38,14 @@ public class AzureStorageConfig {
3038 public DataLakeServiceClient dataLakeServiceClient () {
3139 return new DataLakeServiceClientBuilder ()
3240 .endpoint ("https://" + accountName + ".dfs.core.windows.net" )
33- .credential (new DefaultAzureCredentialBuilder (). build ())
41+ .credential (buildCredential ())
3442 .buildClient ();
3543 }
44+
45+ private TokenCredential buildCredential () {
46+ if (System .getenv ("IDENTITY_ENDPOINT" ) != null ) {
47+ return new ManagedIdentityCredentialBuilder ().build ();
48+ }
49+ return new DefaultAzureCredentialBuilder ().build ();
50+ }
3651}
0 commit comments