This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 51d344af9a14 CAMEL-22688 Add support for Client Secret Credentials in
Azure Identity authentication for camel-azure-storage-blob component (#19903)
51d344af9a14 is described below
commit 51d344af9a141ec16d45fff4b1e640f777104d7b
Author: tupesanket1999 <[email protected]>
AuthorDate: Wed Nov 12 18:58:08 2025 +0530
CAMEL-22688 Add support for Client Secret Credentials in Azure Identity
authentication for camel-azure-storage-blob component (#19903)
* Support for azure identity user input
* Added generated files
* Generated file formatting fix
---
.../catalog/components/azure-storage-blob.json | 10 +-
.../apache/camel/catalog/main/sensitive-keys.json | 2 +
.../storage/blob/BlobComponentConfigurer.java | 18 +++
.../azure/storage/blob/BlobEndpointConfigurer.java | 18 +++
.../azure/storage/blob/BlobEndpointUriFactory.java | 9 +-
.../azure/storage/blob/azure-storage-blob.json | 10 +-
.../azure/storage/blob/BlobComponent.java | 18 +++
.../azure/storage/blob/BlobConfiguration.java | 39 +++++++
.../storage/blob/client/BlobClientFactory.java | 24 ++++
.../java/org/apache/camel/util/SensitiveUtils.java | 4 +
.../AzureStorageBlobComponentBuilderFactory.java | 48 ++++++++
.../endpoint/dsl/BlobEndpointBuilderFactory.java | 126 +++++++++++++++++++++
12 files changed, 320 insertions(+), 6 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
index b9bcc5fa055b..ee4a608f6b56 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
@@ -60,7 +60,10 @@
"healthCheckConsumerEnabled": { "index": 33, "kind": "property",
"displayName": "Health Check Consumer Enabled", "group": "health", "label":
"health", "required": false, "type": "boolean", "javaType": "boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Used for enabling or disabling all consumer based health checks
from this component" },
"healthCheckProducerEnabled": { "index": 34, "kind": "property",
"displayName": "Health Check Producer Enabled", "group": "health", "label":
"health", "required": false, "type": "boolean", "javaType": "boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Used for enabling or disabling all producer based health checks
from this component. Notice: Camel has by default disabled all producer based
health-checks. You can turn on produce [...]
"accessKey": { "index": 35, "kind": "property", "displayName": "Access
Key", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Access key for the
associated azure account name to be used for authentication with azure blob
serv [...]
- "sourceBlobAccessKey": { "index": 36, "kind": "property", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an acc [...]
+ "azureClientId": { "index": 36, "kind": "property", "displayName": "Azure
Client Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client ID for
authentication with Azure Identity" },
+ "azureClientSecret": { "index": 37, "kind": "property", "displayName":
"Azure Client Secret", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client Secret for
authentication with Azure Identity" },
+ "azureTenantId": { "index": 38, "kind": "property", "displayName": "Azure
Tenant Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Tenant ID for
authentication with Azure Identity" },
+ "sourceBlobAccessKey": { "index": 39, "kind": "property", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an acc [...]
},
"headers": {
"CamelAzureStorageBlobOperation": { "index": 0, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType":
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition",
"enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer",
"listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink",
"uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList",
"getBlobBlockList", "createAppendBlob" [...]
@@ -183,6 +186,9 @@
"timeUnit": { "index": 50, "kind": "parameter", "displayName": "Time
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false,
"type": "enum", "javaType": "java.util.concurrent.TimeUnit", "enum": [
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS",
"DAYS" ], "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and
delay options." },
"useFixedDelay": { "index": 51, "kind": "parameter", "displayName": "Use
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": true, "description":
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in
JDK for details." },
"accessKey": { "index": 52, "kind": "parameter", "displayName": "Access
Key", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Access key for the
associated azure account name to be used for authentication with azure blob ser
[...]
- "sourceBlobAccessKey": { "index": 53, "kind": "parameter", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an ac [...]
+ "azureClientId": { "index": 53, "kind": "parameter", "displayName": "Azure
Client Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client ID for
authentication with Azure Identity" },
+ "azureClientSecret": { "index": 54, "kind": "parameter", "displayName":
"Azure Client Secret", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client Secret for
authentication with Azure Identity" },
+ "azureTenantId": { "index": 55, "kind": "parameter", "displayName": "Azure
Tenant Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Tenant ID for
authentication with Azure Identity" },
+ "sourceBlobAccessKey": { "index": 56, "kind": "parameter", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an ac [...]
}
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
index 08314a8dc5d1..a4f0def9dd5a 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
@@ -15,6 +15,8 @@
"authkey",
"authorizationtoken",
"authtoken",
+ "azureclientid",
+ "azureclientsecret",
"blobaccesskey",
"blobstoragesharedkeycredential",
"certresourcepassword",
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
index 4f4a6f0c93f8..c63264718107 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
+++
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
@@ -34,6 +34,12 @@ public class BlobComponentConfigurer extends
PropertyConfigurerSupport implement
case "accessKey":
getOrCreateConfiguration(target).setAccessKey(property(camelContext,
java.lang.String.class, value)); return true;
case "autowiredenabled":
case "autowiredEnabled":
target.setAutowiredEnabled(property(camelContext, boolean.class, value));
return true;
+ case "azureclientid":
+ case "azureClientId":
getOrCreateConfiguration(target).setAzureClientId(property(camelContext,
java.lang.String.class, value)); return true;
+ case "azureclientsecret":
+ case "azureClientSecret":
getOrCreateConfiguration(target).setAzureClientSecret(property(camelContext,
java.lang.String.class, value)); return true;
+ case "azuretenantid":
+ case "azureTenantId":
getOrCreateConfiguration(target).setAzureTenantId(property(camelContext,
java.lang.String.class, value)); return true;
case "blobname":
case "blobName":
getOrCreateConfiguration(target).setBlobName(property(camelContext,
java.lang.String.class, value)); return true;
case "bloboffset":
@@ -114,6 +120,12 @@ public class BlobComponentConfigurer extends
PropertyConfigurerSupport implement
case "accessKey": return java.lang.String.class;
case "autowiredenabled":
case "autowiredEnabled": return boolean.class;
+ case "azureclientid":
+ case "azureClientId": return java.lang.String.class;
+ case "azureclientsecret":
+ case "azureClientSecret": return java.lang.String.class;
+ case "azuretenantid":
+ case "azureTenantId": return java.lang.String.class;
case "blobname":
case "blobName": return java.lang.String.class;
case "bloboffset":
@@ -190,6 +202,12 @@ public class BlobComponentConfigurer extends
PropertyConfigurerSupport implement
case "accessKey": return
getOrCreateConfiguration(target).getAccessKey();
case "autowiredenabled":
case "autowiredEnabled": return target.isAutowiredEnabled();
+ case "azureclientid":
+ case "azureClientId": return
getOrCreateConfiguration(target).getAzureClientId();
+ case "azureclientsecret":
+ case "azureClientSecret": return
getOrCreateConfiguration(target).getAzureClientSecret();
+ case "azuretenantid":
+ case "azureTenantId": return
getOrCreateConfiguration(target).getAzureTenantId();
case "blobname":
case "blobName": return getOrCreateConfiguration(target).getBlobName();
case "bloboffset":
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
index 64516d8c589b..2272ffa1d2fa 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
+++
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
@@ -25,6 +25,12 @@ public class BlobEndpointConfigurer extends
PropertyConfigurerSupport implements
switch (ignoreCase ? name.toLowerCase() : name) {
case "accesskey":
case "accessKey":
target.getConfiguration().setAccessKey(property(camelContext,
java.lang.String.class, value)); return true;
+ case "azureclientid":
+ case "azureClientId":
target.getConfiguration().setAzureClientId(property(camelContext,
java.lang.String.class, value)); return true;
+ case "azureclientsecret":
+ case "azureClientSecret":
target.getConfiguration().setAzureClientSecret(property(camelContext,
java.lang.String.class, value)); return true;
+ case "azuretenantid":
+ case "azureTenantId":
target.getConfiguration().setAzureTenantId(property(camelContext,
java.lang.String.class, value)); return true;
case "backofferrorthreshold":
case "backoffErrorThreshold":
target.setBackoffErrorThreshold(property(camelContext, int.class, value));
return true;
case "backoffidlethreshold":
@@ -133,6 +139,12 @@ public class BlobEndpointConfigurer extends
PropertyConfigurerSupport implements
switch (ignoreCase ? name.toLowerCase() : name) {
case "accesskey":
case "accessKey": return java.lang.String.class;
+ case "azureclientid":
+ case "azureClientId": return java.lang.String.class;
+ case "azureclientsecret":
+ case "azureClientSecret": return java.lang.String.class;
+ case "azuretenantid":
+ case "azureTenantId": return java.lang.String.class;
case "backofferrorthreshold":
case "backoffErrorThreshold": return int.class;
case "backoffidlethreshold":
@@ -237,6 +249,12 @@ public class BlobEndpointConfigurer extends
PropertyConfigurerSupport implements
switch (ignoreCase ? name.toLowerCase() : name) {
case "accesskey":
case "accessKey": return target.getConfiguration().getAccessKey();
+ case "azureclientid":
+ case "azureClientId": return
target.getConfiguration().getAzureClientId();
+ case "azureclientsecret":
+ case "azureClientSecret": return
target.getConfiguration().getAzureClientSecret();
+ case "azuretenantid":
+ case "azureTenantId": return
target.getConfiguration().getAzureTenantId();
case "backofferrorthreshold":
case "backoffErrorThreshold": return target.getBackoffErrorThreshold();
case "backoffidlethreshold":
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
index 56ffbab6ec98..b1d25d321841 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
+++
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
@@ -23,9 +23,12 @@ public class BlobEndpointUriFactory extends
org.apache.camel.support.component.E
private static final Set<String> SECRET_PROPERTY_NAMES;
private static final Map<String, String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(54);
+ Set<String> props = new HashSet<>(57);
props.add("accessKey");
props.add("accountName");
+ props.add("azureClientId");
+ props.add("azureClientSecret");
+ props.add("azureTenantId");
props.add("backoffErrorThreshold");
props.add("backoffIdleThreshold");
props.add("backoffMultiplier");
@@ -79,8 +82,10 @@ public class BlobEndpointUriFactory extends
org.apache.camel.support.component.E
props.add("timeout");
props.add("useFixedDelay");
PROPERTY_NAMES = Collections.unmodifiableSet(props);
- Set<String> secretProps = new HashSet<>(2);
+ Set<String> secretProps = new HashSet<>(4);
secretProps.add("accessKey");
+ secretProps.add("azureClientId");
+ secretProps.add("azureClientSecret");
secretProps.add("sourceBlobAccessKey");
SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
Map<String, String> prefixes = new HashMap<>(1);
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
index b9bcc5fa055b..ee4a608f6b56 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
+++
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
@@ -60,7 +60,10 @@
"healthCheckConsumerEnabled": { "index": 33, "kind": "property",
"displayName": "Health Check Consumer Enabled", "group": "health", "label":
"health", "required": false, "type": "boolean", "javaType": "boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Used for enabling or disabling all consumer based health checks
from this component" },
"healthCheckProducerEnabled": { "index": 34, "kind": "property",
"displayName": "Health Check Producer Enabled", "group": "health", "label":
"health", "required": false, "type": "boolean", "javaType": "boolean",
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true,
"description": "Used for enabling or disabling all producer based health checks
from this component. Notice: Camel has by default disabled all producer based
health-checks. You can turn on produce [...]
"accessKey": { "index": 35, "kind": "property", "displayName": "Access
Key", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Access key for the
associated azure account name to be used for authentication with azure blob
serv [...]
- "sourceBlobAccessKey": { "index": 36, "kind": "property", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an acc [...]
+ "azureClientId": { "index": 36, "kind": "property", "displayName": "Azure
Client Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client ID for
authentication with Azure Identity" },
+ "azureClientSecret": { "index": 37, "kind": "property", "displayName":
"Azure Client Secret", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client Secret for
authentication with Azure Identity" },
+ "azureTenantId": { "index": 38, "kind": "property", "displayName": "Azure
Tenant Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Tenant ID for
authentication with Azure Identity" },
+ "sourceBlobAccessKey": { "index": 39, "kind": "property", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an acc [...]
},
"headers": {
"CamelAzureStorageBlobOperation": { "index": 0, "kind": "header",
"displayName": "", "group": "producer", "label": "producer", "required": false,
"javaType":
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition",
"enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer",
"listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink",
"uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList",
"getBlobBlockList", "createAppendBlob" [...]
@@ -183,6 +186,9 @@
"timeUnit": { "index": 50, "kind": "parameter", "displayName": "Time
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false,
"type": "enum", "javaType": "java.util.concurrent.TimeUnit", "enum": [
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS",
"DAYS" ], "deprecated": false, "autowired": false, "secret": false,
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and
delay options." },
"useFixedDelay": { "index": 51, "kind": "parameter", "displayName": "Use
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": true, "description":
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in
JDK for details." },
"accessKey": { "index": 52, "kind": "parameter", "displayName": "Access
Key", "group": "security", "label": "security", "required": false, "type":
"string", "javaType": "java.lang.String", "deprecated": false, "autowired":
false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Access key for the
associated azure account name to be used for authentication with azure blob ser
[...]
- "sourceBlobAccessKey": { "index": 53, "kind": "parameter", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an ac [...]
+ "azureClientId": { "index": 53, "kind": "parameter", "displayName": "Azure
Client Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client ID for
authentication with Azure Identity" },
+ "azureClientSecret": { "index": 54, "kind": "parameter", "displayName":
"Azure Client Secret", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Client Secret for
authentication with Azure Identity" },
+ "azureTenantId": { "index": 55, "kind": "parameter", "displayName": "Azure
Tenant Id", "group": "security", "label": "security", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Azure Tenant ID for
authentication with Azure Identity" },
+ "sourceBlobAccessKey": { "index": 56, "kind": "parameter", "displayName":
"Source Blob Access Key", "group": "security", "label": "security", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": true, "configurationClass":
"org.apache.camel.component.azure.storage.blob.BlobConfiguration",
"configurationField": "configuration", "description": "Source Blob Access Key:
for copyblob operation, sadly, we need to have an ac [...]
}
}
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
index 4fad72dafc1b..2b29aebbdb47 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
+++
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
@@ -104,7 +104,25 @@ public class BlobComponent extends HealthCheckComponent {
throw new IllegalArgumentException("When using shared account
key, access key must be provided.");
} else if (AZURE_SAS.equals(configuration.getCredentialType()) &&
configuration.getSasToken() == null) {
throw new IllegalArgumentException("When using Azure SAS, SAS
Token must be provided.");
+ } else if
(AZURE_IDENTITY.equals(configuration.getCredentialType())) {
+ validateAzureIdentityCredentials(configuration);
}
}
}
+
+ private void validateAzureIdentityCredentials(final BlobConfiguration
configuration) {
+ boolean hasClientId = configuration.getAzureClientId() != null &&
!configuration.getAzureClientId().trim().isEmpty();
+ boolean hasClientSecret
+ = configuration.getAzureClientSecret() != null &&
!configuration.getAzureClientSecret().trim().isEmpty();
+ boolean hasTenantId = configuration.getAzureTenantId() != null &&
!configuration.getAzureTenantId().trim().isEmpty();
+
+ // If any client credentials are provided, all three must be provided
+ if ((hasClientId || hasClientSecret || hasTenantId) &&
+ !(hasClientId && hasClientSecret && hasTenantId)) {
+ throw new IllegalArgumentException(
+ "When using AZURE_IDENTITY with client credentials, all
three parameters are required: " +
+ "azureClientId,
azureClientSecret, and azureTenantId. " +
+ "Alternatively, omit all three
to use environment variables or other credential sources.");
+ }
+ }
}
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
index 5c7aef4f8f42..8bbf060d5d2c 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
+++
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
@@ -107,6 +107,12 @@ public class BlobConfiguration implements Cloneable {
private boolean leaseBlob;
@UriParam(label = "common", defaultValue = "60")
private Integer leaseDurationInSeconds = 60;
+ @UriParam(label = "security", secret = true)
+ private String azureClientId;
+ @UriParam(label = "security", secret = true)
+ private String azureClientSecret;
+ @UriParam(label = "security")
+ private String azureTenantId;
/**
* Azure account name to be used for authentication with azure blob
services
@@ -503,6 +509,39 @@ public class BlobConfiguration implements Cloneable {
this.leaseDurationInSeconds = leaseDurationInSeconds;
}
+ /**
+ * Azure Client ID for authentication with Azure Identity
+ */
+ public String getAzureClientId() {
+ return azureClientId;
+ }
+
+ public void setAzureClientId(String azureClientId) {
+ this.azureClientId = azureClientId;
+ }
+
+ /**
+ * Azure Client Secret for authentication with Azure Identity
+ */
+ public String getAzureClientSecret() {
+ return azureClientSecret;
+ }
+
+ public void setAzureClientSecret(String azureClientSecret) {
+ this.azureClientSecret = azureClientSecret;
+ }
+
+ /**
+ * Azure Tenant ID for authentication with Azure Identity
+ */
+ public String getAzureTenantId() {
+ return azureTenantId;
+ }
+
+ public void setAzureTenantId(String azureTenantId) {
+ this.azureTenantId = azureTenantId;
+ }
+
// *************************************************
//
// *************************************************
diff --git
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
index 4798bfc2824f..35640cb7233d 100644
---
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
+++
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
@@ -17,6 +17,8 @@
package org.apache.camel.component.azure.storage.blob.client;
import com.azure.core.credential.AzureSasCredential;
+import com.azure.identity.ClientSecretCredential;
+import com.azure.identity.ClientSecretCredentialBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
@@ -45,6 +47,14 @@ public final class BlobClientFactory {
blobServiceClientBuilder.credential(getSharedKeyCredential(configuration));
} else if (AZURE_SAS.equals(configuration.getCredentialType())) {
blobServiceClientBuilder.credential(getAzureSasCredential(configuration));
+ } else if (AZURE_IDENTITY.equals(configuration.getCredentialType())) {
+ if (hasClientSecretCredentials(configuration)) {
+ // Use provided client credentials
+
blobServiceClientBuilder.credential(getClientSecretCredential(configuration));
+ } else {
+ // Fall back to DefaultAzureCredential (environment variables)
+ blobServiceClientBuilder.credential(new
DefaultAzureCredentialBuilder().build());
+ }
} else {
blobServiceClientBuilder.credential(new
DefaultAzureCredentialBuilder().build());
}
@@ -68,4 +78,18 @@ public final class BlobClientFactory {
private static AzureSasCredential getAzureSasCredential(final
BlobConfiguration configuration) {
return new AzureSasCredential(configuration.getSasToken());
}
+
+ private static boolean hasClientSecretCredentials(final BlobConfiguration
configuration) {
+ return !isEmpty(configuration.getAzureClientId()) &&
+ !isEmpty(configuration.getAzureClientSecret()) &&
+ !isEmpty(configuration.getAzureTenantId());
+ }
+
+ private static ClientSecretCredential getClientSecretCredential(final
BlobConfiguration configuration) {
+ return new ClientSecretCredentialBuilder()
+ .clientId(configuration.getAzureClientId())
+ .clientSecret(configuration.getAzureClientSecret())
+ .tenantId(configuration.getAzureTenantId())
+ .build();
+ }
}
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
b/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
index 590ce27fbcde..24e0c2a3e703 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
@@ -44,6 +44,8 @@ public final class SensitiveUtils {
"authkey",
"authorizationtoken",
"authtoken",
+ "azureclientid",
+ "azureclientsecret",
"blobaccesskey",
"blobstoragesharedkeycredential",
"certresourcepassword",
@@ -131,6 +133,8 @@ public final class SensitiveUtils {
+ "|\\Qauthkey\\E"
+
"|\\Qauthorizationtoken\\E"
+ "|\\Qauthtoken\\E"
+ + "|\\Qazureclientid\\E"
+ +
"|\\Qazureclientsecret\\E"
+ "|\\Qblobaccesskey\\E"
+
"|\\Qblobstoragesharedkeycredential\\E"
+
"|\\Qcertresourcepassword\\E"
diff --git
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
index 20fad6d074d7..65a5306e9a0d 100644
---
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
+++
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
@@ -709,6 +709,51 @@ public interface AzureStorageBlobComponentBuilderFactory {
return this;
}
+ /**
+ * Azure Client ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientId the value to set
+ * @return the dsl builder
+ */
+ default AzureStorageBlobComponentBuilder
azureClientId(java.lang.String azureClientId) {
+ doSetProperty("azureClientId", azureClientId);
+ return this;
+ }
+
+ /**
+ * Azure Client Secret for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientSecret the value to set
+ * @return the dsl builder
+ */
+ default AzureStorageBlobComponentBuilder
azureClientSecret(java.lang.String azureClientSecret) {
+ doSetProperty("azureClientSecret", azureClientSecret);
+ return this;
+ }
+
+ /**
+ * Azure Tenant ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureTenantId the value to set
+ * @return the dsl builder
+ */
+ default AzureStorageBlobComponentBuilder
azureTenantId(java.lang.String azureTenantId) {
+ doSetProperty("azureTenantId", azureTenantId);
+ return this;
+ }
+
/**
* Source Blob Access Key: for copyblob operation, sadly, we need to
* have an accessKey for the source blob we want to copy Passing an
@@ -782,6 +827,9 @@ public interface AzureStorageBlobComponentBuilderFactory {
case "healthCheckConsumerEnabled": ((BlobComponent)
component).setHealthCheckConsumerEnabled((boolean) value); return true;
case "healthCheckProducerEnabled": ((BlobComponent)
component).setHealthCheckProducerEnabled((boolean) value); return true;
case "accessKey": getOrCreateConfiguration((BlobComponent)
component).setAccessKey((java.lang.String) value); return true;
+ case "azureClientId": getOrCreateConfiguration((BlobComponent)
component).setAzureClientId((java.lang.String) value); return true;
+ case "azureClientSecret": getOrCreateConfiguration((BlobComponent)
component).setAzureClientSecret((java.lang.String) value); return true;
+ case "azureTenantId": getOrCreateConfiguration((BlobComponent)
component).setAzureTenantId((java.lang.String) value); return true;
case "sourceBlobAccessKey":
getOrCreateConfiguration((BlobComponent)
component).setSourceBlobAccessKey((java.lang.String) value); return true;
default: return false;
}
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
index cd52a47c7863..96390e401e9b 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
@@ -1075,6 +1075,48 @@ public interface BlobEndpointBuilderFactory {
doSetProperty("accessKey", accessKey);
return this;
}
+ /**
+ * Azure Client ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientId the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointConsumerBuilder azureClientId(String
azureClientId) {
+ doSetProperty("azureClientId", azureClientId);
+ return this;
+ }
+ /**
+ * Azure Client Secret for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientSecret the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointConsumerBuilder azureClientSecret(String
azureClientSecret) {
+ doSetProperty("azureClientSecret", azureClientSecret);
+ return this;
+ }
+ /**
+ * Azure Tenant ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureTenantId the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointConsumerBuilder azureTenantId(String
azureTenantId) {
+ doSetProperty("azureTenantId", azureTenantId);
+ return this;
+ }
/**
* Source Blob Access Key: for copyblob operation, sadly, we need to
* have an accessKey for the source blob we want to copy Passing an
@@ -2203,6 +2245,48 @@ public interface BlobEndpointBuilderFactory {
doSetProperty("accessKey", accessKey);
return this;
}
+ /**
+ * Azure Client ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientId the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointProducerBuilder azureClientId(String
azureClientId) {
+ doSetProperty("azureClientId", azureClientId);
+ return this;
+ }
+ /**
+ * Azure Client Secret for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientSecret the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointProducerBuilder azureClientSecret(String
azureClientSecret) {
+ doSetProperty("azureClientSecret", azureClientSecret);
+ return this;
+ }
+ /**
+ * Azure Tenant ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureTenantId the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointProducerBuilder azureTenantId(String
azureTenantId) {
+ doSetProperty("azureTenantId", azureTenantId);
+ return this;
+ }
/**
* Source Blob Access Key: for copyblob operation, sadly, we need to
* have an accessKey for the source blob we want to copy Passing an
@@ -2831,6 +2915,48 @@ public interface BlobEndpointBuilderFactory {
doSetProperty("accessKey", accessKey);
return this;
}
+ /**
+ * Azure Client ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientId the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointBuilder azureClientId(String azureClientId) {
+ doSetProperty("azureClientId", azureClientId);
+ return this;
+ }
+ /**
+ * Azure Client Secret for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureClientSecret the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointBuilder azureClientSecret(String
azureClientSecret) {
+ doSetProperty("azureClientSecret", azureClientSecret);
+ return this;
+ }
+ /**
+ * Azure Tenant ID for authentication with Azure Identity.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: security
+ *
+ * @param azureTenantId the value to set
+ * @return the dsl builder
+ */
+ default BlobEndpointBuilder azureTenantId(String azureTenantId) {
+ doSetProperty("azureTenantId", azureTenantId);
+ return this;
+ }
/**
* Source Blob Access Key: for copyblob operation, sadly, we need to
* have an accessKey for the source blob we want to copy Passing an