diff --git a/Lombiq.Hosting.Azure.ApplicationInsights/ApplicationInsightsOptions.cs b/Lombiq.Hosting.Azure.ApplicationInsights/ApplicationInsightsOptions.cs
index ca78802..564c389 100644
--- a/Lombiq.Hosting.Azure.ApplicationInsights/ApplicationInsightsOptions.cs
+++ b/Lombiq.Hosting.Azure.ApplicationInsights/ApplicationInsightsOptions.cs
@@ -1,3 +1,4 @@
+using Lombiq.Hosting.Azure.ApplicationInsights.Models;
using Microsoft.ApplicationInsights.DataContracts;
using System;
using System.Text.RegularExpressions;
@@ -28,6 +29,7 @@ public class ApplicationInsightsOptions
/// documentation for more info: .
///
+ [Obsolete("Microsoft Entra authentication is the only supported method from 30 September 2025. API key authentication will be removed.")]
public string QuickPulseTelemetryModuleAuthenticationApiKey { get; set; }
///
@@ -69,6 +71,17 @@ public class ApplicationInsightsOptions
///
public bool EnableClientSideTracking { get; set; } = true;
+ ///
+ /// Gets or sets a value indicating whether to use Entra authentication and which type.
+ ///
+ public EntraAuthenticationType EntraAuthenticationType { get; set; }
+
+ ///
+ /// Gets or sets the ServicePrincipalCredentials of the Microsoft Entra application used to secure the control
+ /// channel.
+ ///
+ public ServicePrincipalCredentials ServicePrincipalCredentials { get; set; }
+
///
/// Gets or sets a value indicating whether to work in kind of a debug mode completely offline. Telemetry will still
/// show up in the Debug window.
diff --git a/Lombiq.Hosting.Azure.ApplicationInsights/Extensions/ApplicationInsightsInitializerExtensions.cs b/Lombiq.Hosting.Azure.ApplicationInsights/Extensions/ApplicationInsightsInitializerExtensions.cs
index 7cf79e8..fdb2c52 100644
--- a/Lombiq.Hosting.Azure.ApplicationInsights/Extensions/ApplicationInsightsInitializerExtensions.cs
+++ b/Lombiq.Hosting.Azure.ApplicationInsights/Extensions/ApplicationInsightsInitializerExtensions.cs
@@ -1,4 +1,6 @@
-using Lombiq.Hosting.Azure.ApplicationInsights;
+using Azure.Identity;
+using Lombiq.Hosting.Azure.ApplicationInsights;
+using Lombiq.Hosting.Azure.ApplicationInsights.Models;
using Lombiq.Hosting.Azure.ApplicationInsights.Services;
using Lombiq.Hosting.Azure.ApplicationInsights.TelemetryInitializers;
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
@@ -35,6 +37,24 @@ public static OrchardCoreBuilder AddOrchardCoreApplicationInsightsTelemetry(
.GetSection("OrchardCore:Lombiq_Hosting_Azure_ApplicationInsights");
applicationInsightsConfigSection.Bind(applicationInsightsOptions);
+ services.Configure(config =>
+ {
+ if (applicationInsightsOptions.EntraAuthenticationType == EntraAuthenticationType.ServicePrincipal)
+ {
+ var credential = new ClientSecretCredential(
+ applicationInsightsOptions.ServicePrincipalCredentials.TenantId,
+ applicationInsightsOptions.ServicePrincipalCredentials.ClientId,
+ applicationInsightsOptions.ServicePrincipalCredentials.ClientSecret);
+ config.SetAzureTokenCredential(credential);
+ }
+
+ if (applicationInsightsOptions.EntraAuthenticationType == EntraAuthenticationType.ManagedIdentity)
+ {
+ var credential = new DefaultAzureCredential();
+ config.SetAzureTokenCredential(credential);
+ }
+ });
+
if (string.IsNullOrEmpty(applicationInsightsServiceOptions?.ConnectionString) &&
#pragma warning disable CS0618 // Type or member is obsolete
string.IsNullOrEmpty(applicationInsightsServiceOptions?.InstrumentationKey) &&
@@ -61,8 +81,14 @@ public static OrchardCoreBuilder AddOrchardCoreApplicationInsightsTelemetry(
services.ConfigureTelemetryModule(
(module, _) => module.EnableSqlCommandTextInstrumentation = applicationInsightsOptions.EnableSqlCommandTextInstrumentation);
- services.ConfigureTelemetryModule(
- (module, _) => module.AuthenticationApiKey = applicationInsightsOptions.QuickPulseTelemetryModuleAuthenticationApiKey);
+#pragma warning disable CS0618 // Type or member is obsolete
+ if (applicationInsightsOptions.EntraAuthenticationType == EntraAuthenticationType.None &&
+ !string.IsNullOrEmpty(applicationInsightsOptions.QuickPulseTelemetryModuleAuthenticationApiKey))
+ {
+ services.ConfigureTelemetryModule(
+ (module, _) => module.AuthenticationApiKey = applicationInsightsOptions.QuickPulseTelemetryModuleAuthenticationApiKey);
+ }
+#pragma warning restore CS0618 // Type or member is obsolete
services.AddSingleton();
services.AddSingleton();
diff --git a/Lombiq.Hosting.Azure.ApplicationInsights/Lombiq.Hosting.Azure.ApplicationInsights.csproj b/Lombiq.Hosting.Azure.ApplicationInsights/Lombiq.Hosting.Azure.ApplicationInsights.csproj
index a63ba80..5d4dae6 100644
--- a/Lombiq.Hosting.Azure.ApplicationInsights/Lombiq.Hosting.Azure.ApplicationInsights.csproj
+++ b/Lombiq.Hosting.Azure.ApplicationInsights/Lombiq.Hosting.Azure.ApplicationInsights.csproj
@@ -33,7 +33,7 @@
-
+
diff --git a/Lombiq.Hosting.Azure.ApplicationInsights/Models/EntraAuthenticationType.cs b/Lombiq.Hosting.Azure.ApplicationInsights/Models/EntraAuthenticationType.cs
new file mode 100644
index 0000000..0848be0
--- /dev/null
+++ b/Lombiq.Hosting.Azure.ApplicationInsights/Models/EntraAuthenticationType.cs
@@ -0,0 +1,19 @@
+namespace Lombiq.Hosting.Azure.ApplicationInsights.Models;
+
+public enum EntraAuthenticationType
+{
+ ///
+ /// Don't use Entra authentication.
+ ///
+ None,
+
+ ///
+ /// Use Managed Identity.
+ ///
+ ManagedIdentity,
+
+ ///
+ /// Use a service principal. This requires setting up ServicePrincipalCredentials.
+ ///
+ ServicePrincipal,
+}
diff --git a/Lombiq.Hosting.Azure.ApplicationInsights/ServicePrincipalCredentials.cs b/Lombiq.Hosting.Azure.ApplicationInsights/ServicePrincipalCredentials.cs
new file mode 100644
index 0000000..068878a
--- /dev/null
+++ b/Lombiq.Hosting.Azure.ApplicationInsights/ServicePrincipalCredentials.cs
@@ -0,0 +1,19 @@
+namespace Lombiq.Hosting.Azure.ApplicationInsights;
+
+public class ServicePrincipalCredentials
+{
+ ///
+ /// Gets or sets the (directory) tenant ID of the Microsoft Entra application used to secure the control channel.
+ ///
+ public string TenantId { get; set; }
+
+ ///
+ /// Gets or sets the application (client) ID of the Microsoft Entra application used to secure the control channel.
+ ///
+ public string ClientId { get; set; }
+
+ ///
+ /// Gets or sets the client secret of the Microsoft Entra application used to secure the control channel.
+ ///
+ public string ClientSecret { get; set; }
+}
diff --git a/Readme.md b/Readme.md
index 7787eca..e1fc5d0 100644
--- a/Readme.md
+++ b/Readme.md
@@ -86,6 +86,7 @@ The module has its own configuration for further options. These need to come fro
},
"OrchardCore": {
"Lombiq_Hosting_Azure_ApplicationInsights": {
+ // Deprecated, do not use in new projects.
"QuickPulseTelemetryModuleAuthenticationApiKey": "your API key here"
}
}
@@ -93,12 +94,63 @@ The module has its own configuration for further options. These need to come fro
```
-See the [`ApplicationInsightsOptions` class](Lombiq.Hosting.Azure.ApplicationInsights/ApplicationInsightsOptions.cs) for all options and details. We recommend configuring at least `QuickPulseTelemetryModuleAuthenticationApiKey`.
+> ⚠ Use of QuickPulseTelemetryModuleAuthenticationApiKey is deprecated and will be officially unsupported starting 30 September 2025. See [Entra Authentication for the Live Metrics control channel](#entra-authentication-for-the-live-metrics-control-channel) for more information.
+
+See the [`ApplicationInsightsOptions` class](Lombiq.Hosting.Azure.ApplicationInsights/ApplicationInsightsOptions.cs) for all options and details.
Note that while telemetry from background tasks is collected in form of dependency operations it'll be collected even if `EnableDependencyTrackingTelemetryModule` is `false`.
If you use the security defaults from [Lombiq Helpful Libraries - Orchard Core Libraries - Security](https://github.com/Lombiq/Helpful-Libraries/blob/dev/Lombiq.HelpfulLibraries.OrchardCore/Docs/Security.md), then the security headers necessary to use Application Insight's client-side tracking will automatically be added.
+### Entra Authentication for the Live Metrics control channel
+
+Starting 30 September 2025, authentication using API keys is no longer supported for [securing the Live Metrics control channel](https://learn.microsoft.com/en-us/azure/azure-monitor/app/live-stream#secure-the-control-channel). Instead, you'll have to set up Entra Authentication for that. You may omit this if not needed; configuring the connection string is necessary in any case, and enough for simply collecting telemetry. Entra Authentication is only needed if you want to control the Live Metrics stream from the Azure Portal, like filtering telemetry.
+
+#### Setting up Entra Authentication for Application Insights
+
+> ⚠ This section is required if you have disabled `Local Authentication` on your AI resource, see [the docs](https://learn.microsoft.com/en-us/azure/azure-monitor/app/azure-ad-authentication?WT.mc_id=Portal-AppInsightsExtension&tabs=net#disable-local-authentication).
+
+If you want to use Entra Authentication for Application Insights, or if you have disabled `Local Authentication` on your AI resource, you will have to set the `EntraAuthenticationType` option to the authentication type you want to use (`ManagedIdentity` or `ServicePrincipal`) in the `Lombiq_Hosting_Azure_ApplicationInsights` section of your configuration like below.
+
+```json5
+{
+ "OrchardCore": {
+ "Lombiq_Hosting_Azure_ApplicationInsights": {
+ "EntraAuthenticationType": "ManagedIdentity"
+ }
+ }
+}
+```
+
+To set up Entra Authentication for an application hosted on Azure you will have to set up a Managed Identity for the application and give it the `Monitoring Metrics Publisher` role (see more on assigning Azure roles [here](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal)) to be able to publish metrics to AI. A managed identity will allow your app to authenticate with the Application Insights resource; see how to set it up for specific Azure services [here](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/managed-identities-status). We recommend using the simpler system-assigned identity option, since then you can easily allow your app's identity to get a role under the Application Insights resource. Note that it might take a few minutes for the managed identity to work; until then, Live Metrics won't be available.
+
+You can also use a service principal to authenticate. To set this up, you will have to provide the service principal credentials in the configuration. See the [Service principal](#service-principal) section for more information. This is also the only way to authenticate if you are using a non-Azure (or local) environment - or an Azure resource that does not support Managed Identities.
+
+Once Entra Authentication is set up and the `ConnectionString` has been properly set, you should be able to control the Live Metrics stream from the Azure Portal, like filtering telemetry.
+
+#### Service principal
+
+Using a Service Principal is the only way to authenticate using Entra authentication if you are using a non-Azure (or local) environment.
+
+If you want to use the Service Principal method for your Application Insights resource, you should set the `EntraAuthenticationType` option to `ServicePrincipal` in the `Lombiq_Hosting_Azure_ApplicationInsights` section of your configuration. To securely control the Live Metrics stream with Entra ID you will also have to provide the credentials of the service principal; to set this up, [see the docs](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal) (you'll need to use the [client secret authentication option](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal#option-3-create-a-new-client-secret)).
+
+```json5
+{
+ "OrchardCore": {
+ "Lombiq_Hosting_Azure_ApplicationInsights": {
+ "EntraAuthenticationType": "ServicePrincipal",
+ "ServicePrincipalCredentials": {
+ "TenantId": "your service principal tenant id",
+ "ClientId": "your service principal client id",
+ "ClientSecret": "your service principal client secret"
+ }
+ }
+ }
+}
+```
+
+For more information or scenarios not described here, see the [official documentation](https://learn.microsoft.com/en-us/azure/azure-monitor/app/azure-ad-authentication).
+
### Using collected data
All the collected data will be available in the Azure Portal as usual. Some custom properties will be added to all suitable telemetry with the `"OrchardCore."` prefix.