diff --git a/DirectConnector/Configuration/ConnectorOptions.cs b/DirectConnector/Configuration/ConnectorOptions.cs
index 4e57886..337793d 100644
--- a/DirectConnector/Configuration/ConnectorOptions.cs
+++ b/DirectConnector/Configuration/ConnectorOptions.cs
@@ -17,6 +17,18 @@ public class ConnectorOptions
///
public const string SectionName = "Connectors";
+ ///
+ /// When true, use for local development.
+ /// Set to true in local.settings.json for local dev; leave false (default) in Azure.
+ ///
+ public bool UseAzureCliCredential { get; set; }
+
+ ///
+ /// Managed identity client ID for user-assigned identity.
+ /// Leave unset (null or empty) for system-assigned managed identity (default).
+ ///
+ public string? ManagedIdentityClientId { get; set; }
+
///
/// Office365 connector options.
///
@@ -88,13 +100,6 @@ public class TeamsOptions
///
[Required(ErrorMessage = "Teams ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -107,13 +112,6 @@ public class Office365Options
///
[Required(ErrorMessage = "Office365 ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -126,13 +124,6 @@ public class SharePointOptions
///
[Required(ErrorMessage = "SharePoint ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -145,13 +136,6 @@ public class OneDriveOptions
///
[Required(ErrorMessage = "OneDrive ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -164,13 +148,6 @@ public class MsGraphOptions
///
[Required(ErrorMessage = "Connectors:MsGraph:ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -183,13 +160,6 @@ public class AzureBlobOptions
///
[Required(ErrorMessage = "Connectors:AzureBlob:ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -202,13 +172,6 @@ public class SmtpOptions
///
[Required(ErrorMessage = "Connectors:Smtp:ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -221,13 +184,6 @@ public class MqOptions
///
[Required(ErrorMessage = "Connectors:Mq:ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -240,13 +196,6 @@ public class Office365UsersOptions
///
[Required(ErrorMessage = "Connectors:Office365Users:ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
///
@@ -259,11 +208,4 @@ public class AzureLogAnalyticsOptions
///
[Required(ErrorMessage = "Connectors:AzureLogAnalytics:ConnectionRuntimeUrl is required.")]
public string ConnectionRuntimeUrl { get; set; } = string.Empty;
-
- ///
- /// Managed identity client ID for user-assigned identity.
- /// Set to empty string for system-assigned managed identity.
- /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.).
- ///
- public string? ManagedIdentityClientId { get; set; }
}
diff --git a/DirectConnector/Program.cs b/DirectConnector/Program.cs
index e88984c..0888389 100644
--- a/DirectConnector/Program.cs
+++ b/DirectConnector/Program.cs
@@ -2,6 +2,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
+using Azure.Core;
+using Azure.Identity;
using DirectConnector.Configuration;
using Microsoft.Azure.Connectors.DirectClient.Azureblob;
using Microsoft.Azure.Connectors.DirectClient.Azureloganalytics;
@@ -35,126 +37,111 @@
services.AddHttpClient();
+ // NOTE: Resolve the credential once for all connector clients.
+ // In Azure: defaults to ManagedIdentityCredential (system-assigned).
+ // For user-assigned MSI: set ManagedIdentityClientId in configuration.
+ // For local dev: set UseAzureCliCredential=true in local.settings.json.
+ services.AddSingleton(serviceProvider =>
+ {
+ var options = serviceProvider.GetRequiredService>().Value;
+
+ if (options.UseAzureCliCredential)
+ {
+ return new AzureCliCredential();
+ }
+
+ if (!string.IsNullOrEmpty(options.ManagedIdentityClientId))
+ {
+ return new ManagedIdentityCredential(
+ ManagedIdentityId.FromUserAssignedClientId(options.ManagedIdentityClientId));
+ }
+
+ return new ManagedIdentityCredential(ManagedIdentityId.SystemAssigned);
+ });
+
// NOTE: Register generated connector clients as singletons.
- // The factory overload lets DI own the instance lifetime and call Dispose,
- // which exercises the ownership-based disposal pattern: the client will
- // dispose its internally-created HttpClient and DefaultAzureCredential.
+ // The factory overload lets DI own the instance lifetime and call Dispose.
+ // All clients share the same credential resolved above.
// NOTE: Validation of ConnectionRuntimeUrl is handled by
// [Required] attribute + ValidateOnStart() at host initialization.
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- // NOTE: When ManagedIdentityClientId is null, use the default constructor so
- // the client relies on DefaultAzureCredential. When ManagedIdentityClientId is non-null
- // (empty string = system-assigned MSI, non-empty = user-assigned MSI), use the MSI constructor.
- return options.Office365.ManagedIdentityClientId != null
- ? new Office365Client(
- options.Office365.ConnectionRuntimeUrl,
- options.Office365.ManagedIdentityClientId)
- : new Office365Client(options.Office365.ConnectionRuntimeUrl);
+ return new Office365Client(options.Office365.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- // NOTE: When ManagedIdentityClientId is null, use the default constructor so
- // the client relies on DefaultAzureCredential. When ManagedIdentityClientId is non-null
- // (empty string = system-assigned MSI, non-empty = user-assigned MSI), use the MSI constructor.
- return options.SharePoint.ManagedIdentityClientId != null
- ? new SharepointonlineClient(
- options.SharePoint.ConnectionRuntimeUrl,
- options.SharePoint.ManagedIdentityClientId)
- : new SharepointonlineClient(options.SharePoint.ConnectionRuntimeUrl);
+ return new SharepointonlineClient(options.SharePoint.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.Teams.ManagedIdentityClientId != null
- ? new TeamsClient(
- options.Teams.ConnectionRuntimeUrl,
- options.Teams.ManagedIdentityClientId)
- : new TeamsClient(options.Teams.ConnectionRuntimeUrl);
+ return new TeamsClient(options.Teams.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.OneDrive.ManagedIdentityClientId != null
- ? new OnedriveforbusinessClient(
- options.OneDrive.ConnectionRuntimeUrl,
- options.OneDrive.ManagedIdentityClientId)
- : new OnedriveforbusinessClient(options.OneDrive.ConnectionRuntimeUrl);
+ return new OnedriveforbusinessClient(options.OneDrive.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.MsGraph.ManagedIdentityClientId != null
- ? new MsgraphgroupsanduserClient(
- options.MsGraph.ConnectionRuntimeUrl,
- options.MsGraph.ManagedIdentityClientId)
- : new MsgraphgroupsanduserClient(options.MsGraph.ConnectionRuntimeUrl);
+ return new MsgraphgroupsanduserClient(options.MsGraph.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.AzureBlob.ManagedIdentityClientId != null
- ? new AzureblobClient(
- options.AzureBlob.ConnectionRuntimeUrl,
- options.AzureBlob.ManagedIdentityClientId)
- : new AzureblobClient(options.AzureBlob.ConnectionRuntimeUrl);
+ return new AzureblobClient(options.AzureBlob.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.Smtp.ManagedIdentityClientId != null
- ? new SmtpClient(
- options.Smtp.ConnectionRuntimeUrl,
- options.Smtp.ManagedIdentityClientId)
- : new SmtpClient(options.Smtp.ConnectionRuntimeUrl);
+ return new SmtpClient(options.Smtp.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.Mq.ManagedIdentityClientId != null
- ? new MqClient(
- options.Mq.ConnectionRuntimeUrl,
- options.Mq.ManagedIdentityClientId)
- : new MqClient(options.Mq.ConnectionRuntimeUrl);
+ return new MqClient(options.Mq.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.Office365Users.ManagedIdentityClientId != null
- ? new Office365usersClient(
- options.Office365Users.ConnectionRuntimeUrl,
- options.Office365Users.ManagedIdentityClientId)
- : new Office365usersClient(options.Office365Users.ConnectionRuntimeUrl);
+ return new Office365usersClient(options.Office365Users.ConnectionRuntimeUrl, credential);
});
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetRequiredService>().Value;
+ var credential = serviceProvider.GetRequiredService();
- return options.AzureLogAnalytics.ManagedIdentityClientId != null
- ? new AzureloganalyticsClient(
- options.AzureLogAnalytics.ConnectionRuntimeUrl,
- options.AzureLogAnalytics.ManagedIdentityClientId)
- : new AzureloganalyticsClient(options.AzureLogAnalytics.ConnectionRuntimeUrl);
+ return new AzureloganalyticsClient(options.AzureLogAnalytics.ConnectionRuntimeUrl, credential);
});
})
.Build();