diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java index 64903464650..2b6a8793742 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java @@ -28,12 +28,15 @@ import java.nio.file.Path; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; +import com.google.common.base.Splitter; import com.microsoft.applicationinsights.agent.bootstrap.diagnostics.DiagnosticsHelper; import com.microsoft.applicationinsights.agent.internal.wasbootstrap.configuration.Configuration.JmxMetric; import com.microsoft.applicationinsights.agent.internal.wasbootstrap.configuration.Configuration.SamplingOverride; import com.microsoft.applicationinsights.customExceptions.FriendlyException; +import com.microsoft.applicationinsights.internal.authentication.AuthenticationType; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonDataException; import com.squareup.moshi.JsonEncodingException; @@ -81,6 +84,8 @@ public class ConfigurationBuilder { private static final String APPLICATIONINSIGHTS_PREVIEW_METRIC_INTERVAL_SECONDS = "APPLICATIONINSIGHTS_PREVIEW_METRIC_INTERVAL_SECONDS"; + private static final String APPLICATIONINSIGHTS_AUTHENTICATION_STRING = "APPLICATIONINSIGHTS_AUTHENTICATION_STRING"; + // cannot use logger before loading configuration, so need to store warning messages locally until logger is initialized private static final List configurationWarnMessages = new CopyOnWriteArrayList<>(); @@ -113,6 +118,31 @@ private static void overlayProfilerConfiguration(Configuration config) { .parseBoolean(overlayWithEnvVar(APPLICATIONINSIGHTS_PROFILER_ENABLED, Boolean.toString(config.preview.profiler.enabled))); } + private static void overlayAadConfiguration(Configuration config) { + String aadAuthString = getEnvVar(APPLICATIONINSIGHTS_AUTHENTICATION_STRING); + if(aadAuthString != null) { + Map keyValueMap = Splitter.on(";") + .trimResults() + .omitEmptyStrings() + .withKeyValueSeparator("=") + .split(aadAuthString); + String authorization = keyValueMap.get("Authorization"); + if(authorization != null && authorization.equals("AAD")) { + // Override any configuration from json + config.preview.authentication = new Configuration.AadAuthentication(); + config.preview.authentication.enabled = true; + config.preview.authentication.type = AuthenticationType.SAMI; + String clientId = keyValueMap.get("ClientId"); + if(clientId != null && !clientId.isEmpty()) { + // Override type to User Assigned Managed Identity + config.preview.authentication.type = AuthenticationType.UAMI; + config.preview.authentication.clientId = clientId; + } + } + } + + } + private static void loadLogCaptureEnvVar(Configuration config) { String loggingEnvVar = getEnvVar(APPLICATIONINSIGHTS_INSTRUMENTATION_LOGGING_LEVEL); if (loggingEnvVar != null) { @@ -270,7 +300,7 @@ static void overlayEnvVars(Configuration config) throws IOException { addDefaultJmxMetricsIfNotPresent(config); overlayProfilerConfiguration(config); - + overlayAadConfiguration(config); loadInstrumentationEnabledEnvVars(config); } diff --git a/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java b/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java index 08b746cd5aa..cfe80562a49 100644 --- a/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java +++ b/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java @@ -521,6 +521,29 @@ public void shouldOverrideInstrumentationSpringSchedulingEnabled() throws IOExce assertFalse(configuration.instrumentation.springScheduling.enabled); } + @Test + public void shouldOverrideAadAuthenticationConfig() throws IOException { + envVars.set("APPLICATIONINSIGHTS_AUTHENTICATION_STRING", "Authorization=AAD;ClientId=12345678"); + + Configuration configuration = loadConfiguration("applicationinsights_aadauthenv.json"); + ConfigurationBuilder.overlayEnvVars(configuration); + + assertTrue(configuration.preview.authentication.enabled); + assertEquals(AuthenticationType.UAMI, configuration.preview.authentication.type); + assertEquals("12345678", configuration.preview.authentication.clientId); + assertNull(configuration.preview.authentication.clientSecret); + + envVars.set("APPLICATIONINSIGHTS_AUTHENTICATION_STRING", "Authorization=AAD;ClientId="); + + Configuration configuration2 = loadConfiguration("applicationinsights_aadauthenv.json"); + ConfigurationBuilder.overlayEnvVars(configuration2); + + assertTrue(configuration2.preview.authentication.enabled); + assertEquals(AuthenticationType.SAMI, configuration2.preview.authentication.type); + assertNull(configuration2.preview.authentication.clientId); + assertNull(configuration2.preview.authentication.clientSecret); + } + @Test public void shouldUseRpConfigRole() { Configuration configuration = new Configuration(); diff --git a/agent/agent-tooling/src/test/resources/applicationinsights_aadauthenv.json b/agent/agent-tooling/src/test/resources/applicationinsights_aadauthenv.json new file mode 100644 index 00000000000..29d356c9f1a --- /dev/null +++ b/agent/agent-tooling/src/test/resources/applicationinsights_aadauthenv.json @@ -0,0 +1,14 @@ +{ + "connectionString": "InstrumentationKey=00000000-0000-0000-0000-000000000000", + "preview" : { + "authentication" : { + "enabled": false, + "type": "CLIENTSECRET", + "clientId" : "123xyz", + "keePassDatabasePath" : "path/to/keePass", + "tenantId": "tenant123", + "clientSecret": "clientsecret123", + "authorityHost": "https://test.com/microsoft/" + } + } +} diff --git a/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java b/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java index f8df4134b43..06b941e4851 100644 --- a/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java +++ b/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java @@ -291,7 +291,7 @@ public void testTrackPageView() throws Exception { assertNotNull(pv2); assertEquals(new Duration(123456), pv2.getDuration()); - assertEquals("2010-10-10T00:00:00.000+0000", pvdEnvelope2.getTime()); + assertEquals("2010-10-10T00:00:00Z", pvdEnvelope2.getTime()); assertEquals("value", pv2.getProperties().get("key")); assertEquals("a-value", pv2.getProperties().get("a-prop")); assertEquals("another-value", pv2.getProperties().get("another-prop")); @@ -312,7 +312,7 @@ public void testTrackPageView() throws Exception { assertNotNull(pv3); assertEquals(new Duration(123456), pv3.getDuration()); - assertEquals("2010-10-10T00:00:00.000+0000", pvdEnvelope3.getTime()); + assertEquals("2010-10-10T00:00:00Z", pvdEnvelope3.getTime()); assertEquals("value", pv3.getProperties().get("key")); assertEquals("a-value", pv3.getProperties().get("a-prop")); assertEquals("another-value", pv3.getProperties().get("another-prop"));