diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/AzureArcManagedIdentitySource.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/AzureArcManagedIdentitySource.cs index 2b6babecf9..1565413ff7 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/AzureArcManagedIdentitySource.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/AzureArcManagedIdentitySource.cs @@ -29,7 +29,16 @@ internal class AzureArcManagedIdentitySource : AbstractManagedIdentity public static AbstractManagedIdentity Create(RequestContext requestContext) { - string identityEndpoint = EnvironmentVariables.IdentityEndpoint; + string identityEndpoint; + + if (EnvironmentVariables.IdentityEndpoint == null) + { + identityEndpoint = "http://127.0.0.1:40342/metadata/identity/oauth2/token"; + requestContext.Logger.Info(() => "[Managed Identity] Azure Arc was detected through file based detection but the environment variables were not found. Defaulting to known azure arc endpoint."); + } else + { + identityEndpoint = EnvironmentVariables.IdentityEndpoint; + } requestContext.Logger.Info(() => "[Managed Identity] Azure Arc managed identity is available."); diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs index 7df4f81723..2dc27fdc9b 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs @@ -6,6 +6,9 @@ using System.Threading; using Microsoft.Identity.Client.Internal; using Microsoft.Identity.Client.ApiConfig.Parameters; +using Microsoft.Identity.Client.PlatformsCommon.Shared; +using System.IO; +using Microsoft.Identity.Client.Core; namespace Microsoft.Identity.Client.ManagedIdentity { @@ -15,6 +18,8 @@ namespace Microsoft.Identity.Client.ManagedIdentity /// internal class ManagedIdentityClient { + private const string WindowsHimdsFilePath = "%Programfiles%\\AzureConnectedMachineAgent\\himds.exe"; + private const string LinuxHimdsFilePath = "/opt/azcmagent/bin/himds"; private readonly AbstractManagedIdentity _identitySource; public ManagedIdentityClient(RequestContext requestContext) @@ -33,7 +38,7 @@ internal Task SendTokenRequestForManagedIdentityAsync(A // This method tries to create managed identity source for different sources, if none is created then defaults to IMDS. private static AbstractManagedIdentity SelectManagedIdentitySource(RequestContext requestContext) { - return GetManagedIdentitySource() switch + return GetManagedIdentitySource(requestContext.Logger) switch { ManagedIdentitySource.ServiceFabric => ServiceFabricManagedIdentitySource.Create(requestContext), ManagedIdentitySource.AppService => AppServiceManagedIdentitySource.Create(requestContext), @@ -46,7 +51,7 @@ private static AbstractManagedIdentity SelectManagedIdentitySource(RequestContex // Detect managed identity source based on the availability of environment variables. // The result of this method is not cached because reading environment variables is cheap. // This method is perf sensitive any changes should be benchmarked. - internal static ManagedIdentitySource GetManagedIdentitySource() + internal static ManagedIdentitySource GetManagedIdentitySource(ILoggerAdapter logger = null) { string identityEndpoint = EnvironmentVariables.IdentityEndpoint; string identityHeader = EnvironmentVariables.IdentityHeader; @@ -72,7 +77,7 @@ internal static ManagedIdentitySource GetManagedIdentitySource() { return ManagedIdentitySource.CloudShell; } - else if (!string.IsNullOrEmpty(identityEndpoint) && !string.IsNullOrEmpty(imdsEndpoint)) + else if (ValidateAzureArcEnvironment(identityEndpoint, imdsEndpoint, logger)) { return ManagedIdentitySource.AzureArc; } @@ -81,5 +86,33 @@ internal static ManagedIdentitySource GetManagedIdentitySource() return ManagedIdentitySource.DefaultToImds; } } + + // Method to return true if a file exists and is not empty to validate the Azure arc environment. + private static bool ValidateAzureArcEnvironment(string identityEndpoint, string imdsEndpoint, ILoggerAdapter logger) + { + if (!string.IsNullOrEmpty(identityEndpoint) && !string.IsNullOrEmpty(imdsEndpoint)) + { + logger?.Verbose(() => "[Managed Identity] Azure Arc managed identity is available through environment variables."); + return true; + } + + if (DesktopOsHelper.IsWindows() && File.Exists(Environment.ExpandEnvironmentVariables(WindowsHimdsFilePath))) + { + logger?.Verbose(() => "[Managed Identity] Azure Arc managed identity is available through file detection."); + return true; + } + else if (DesktopOsHelper.IsLinux() && File.Exists(LinuxHimdsFilePath)) + { + logger?.Verbose(() => "[Managed Identity] Azure Arc managed identity is available through file detection."); + return true; + } + else + { + logger?.Warning("[Managed Identity] Azure Arc managed identity cannot be configured on a platform other than Windows and Linux."); + } + + logger?.Verbose(() => "[Managed Identity] Azure Arc managed identity is not available."); + return false; + } } }