From 2483baea56cd7f0724bff69a12b7275e679d4ec5 Mon Sep 17 00:00:00 2001 From: Robbie Ginsburg Date: Wed, 18 Jun 2025 07:37:06 -0400 Subject: [PATCH 1/6] Added support for DEFAULT_IDENTITY_CLIENT_ID environment variable in Machine Learning Managed Identity --- .../ManagedIdentity/EnvironmentVariables.cs | 1 + .../MachineLearningManagedIdentitySource.cs | 34 ++++++-- .../Microsoft.Identity.Client/MsalError.cs | 5 ++ .../MsalErrorMessage.cs | 1 + .../PublicApi/net462/PublicAPI.Unshipped.txt | 3 +- .../PublicApi/net472/PublicAPI.Unshipped.txt | 3 +- .../net8.0-android/PublicAPI.Unshipped.txt | 3 +- .../net8.0-ios/PublicAPI.Unshipped.txt | 3 +- .../PublicApi/net8.0/PublicAPI.Unshipped.txt | 3 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 +- .../Core/Helpers/ManagedIdentityTestUtil.cs | 1 + .../Core/Mocks/MockHttpManagerExtensions.cs | 25 +++--- .../MachineLearningTests.cs | 83 ++++++++++++++++++- .../ManagedIdentityTests.cs | 2 - 14 files changed, 137 insertions(+), 33 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/EnvironmentVariables.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/EnvironmentVariables.cs index aed4821dae..65c84a96f1 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/EnvironmentVariables.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/EnvironmentVariables.cs @@ -14,5 +14,6 @@ internal class EnvironmentVariables public static string MsiEndpoint => Environment.GetEnvironmentVariable("MSI_ENDPOINT"); public static string MsiSecret => Environment.GetEnvironmentVariable("MSI_SECRET"); public static string IdentityServerThumbprint => Environment.GetEnvironmentVariable("IDENTITY_SERVER_THUMBPRINT"); + public static string MachineLearningDefaultClientId => Environment.GetEnvironmentVariable("DEFAULT_IDENTITY_CLIENT_ID"); } } diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs index f69f34de7a..9eca8bca41 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs @@ -10,12 +10,16 @@ namespace Microsoft.Identity.Client.ManagedIdentity { internal class MachineLearningManagedIdentitySource : AbstractManagedIdentity { + private const string MachineLearning = "Machine Learning"; + private const string MachineLearningMsiApiVersion = "2017-09-01"; private const string SecretHeaderName = "secret"; private readonly Uri _endpoint; private readonly string _secret; + public const string UnsupportedIdTypeError = "Only client id is supported for user-assigned managed identity in Machine Learning."; // referenced in unit test + public static AbstractManagedIdentity Create(RequestContext requestContext) { requestContext.Logger.Info(() => "[Managed Identity] Machine learning managed identity is available."); @@ -73,21 +77,33 @@ protected override ManagedIdentityRequest CreateRequest(string resource) switch (_requestContext.ServiceBundle.Config.ManagedIdentityId.IdType) { + case AppConfig.ManagedIdentityIdType.SystemAssigned: + _requestContext.Logger.Info("[Managed Identity] Adding system assigned client id to the request."); + // Use the new 2017 constant for older ML-based environment + request.QueryParameters[Constants.ManagedIdentityClientId2017] = EnvironmentVariables.MachineLearningDefaultClientId; // this environment variable is always set in an Azure Machine Learning source + break; + case AppConfig.ManagedIdentityIdType.ClientId: _requestContext.Logger.Info("[Managed Identity] Adding user assigned client id to the request."); // Use the new 2017 constant for older ML-based environment request.QueryParameters[Constants.ManagedIdentityClientId2017] = _requestContext.ServiceBundle.Config.ManagedIdentityId.UserAssignedId; break; - case AppConfig.ManagedIdentityIdType.ResourceId: - _requestContext.Logger.Info("[Managed Identity] Adding user assigned resource id to the request."); - request.QueryParameters[Constants.ManagedIdentityResourceId] = _requestContext.ServiceBundle.Config.ManagedIdentityId.UserAssignedId; - break; - - case AppConfig.ManagedIdentityIdType.ObjectId: - _requestContext.Logger.Info("[Managed Identity] Adding user assigned object id to the request."); - request.QueryParameters[Constants.ManagedIdentityObjectId] = _requestContext.ServiceBundle.Config.ManagedIdentityId.UserAssignedId; - break; + default: + string errorMessage = string.Format( + CultureInfo.InvariantCulture, + MsalErrorMessage.ManagedIdentityInvalidIdType, + "client id is", + MachineLearning); + + var exception = MsalServiceExceptionFactory.CreateManagedIdentityException( + MsalError.InvalidManagedIdentityIdType, + errorMessage, + null, // configuration error + ManagedIdentitySource.MachineLearning, + null); // statusCode is null in this case + + throw exception; } return request; diff --git a/src/client/Microsoft.Identity.Client/MsalError.cs b/src/client/Microsoft.Identity.Client/MsalError.cs index e712c02c77..861d8ef0c3 100644 --- a/src/client/Microsoft.Identity.Client/MsalError.cs +++ b/src/client/Microsoft.Identity.Client/MsalError.cs @@ -1105,6 +1105,11 @@ public static class MsalError /// public const string InvalidManagedIdentityResponse = "invalid_managed_identity_response"; + /// + /// The managed identity's source does not select a specific id type. + /// + public const string InvalidManagedIdentityIdType = "invalid_managed_identity_id_type"; + /// /// Managed Identity error response was received. /// diff --git a/src/client/Microsoft.Identity.Client/MsalErrorMessage.cs b/src/client/Microsoft.Identity.Client/MsalErrorMessage.cs index b1895118aa..7a44e46705 100644 --- a/src/client/Microsoft.Identity.Client/MsalErrorMessage.cs +++ b/src/client/Microsoft.Identity.Client/MsalErrorMessage.cs @@ -415,6 +415,7 @@ public static string InvalidTokenProviderResponseValue(string invalidValueName) public const string ManagedIdentityNoResponseReceived = "[Managed Identity] Authentication unavailable. No response received from the managed identity endpoint."; public const string ManagedIdentityInvalidResponse = "[Managed Identity] Invalid response, the authentication response received did not contain the expected fields."; + public const string ManagedIdentityInvalidIdType = "Only {0} supported for user-assigned managed identity in {1}"; public const string ManagedIdentityJsonParseFailure = "[Managed Identity] MSI returned 200 OK, but the response could not be parsed."; public const string ManagedIdentityUnexpectedResponse = "[Managed Identity] Unexpected exception occurred when parsing the response. See the inner exception for details."; public const string ManagedIdentityExactlyOneScopeExpected = "[Managed Identity] To acquire token for managed identity, exactly one scope must be passed."; diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt index 9b7aaf512c..dbfd7597ed 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int -Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void \ No newline at end of file +Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt index 9b7aaf512c..dbfd7597ed 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int -Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void \ No newline at end of file +Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt index 9b7aaf512c..dbfd7597ed 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int -Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void \ No newline at end of file +Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt index 9b7aaf512c..dbfd7597ed 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int -Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void \ No newline at end of file +Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt index 9b7aaf512c..dbfd7597ed 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int -Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void \ No newline at end of file +Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt index 9b7aaf512c..dbfd7597ed 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int -Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void \ No newline at end of file +Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/tests/Microsoft.Identity.Test.Common/Core/Helpers/ManagedIdentityTestUtil.cs b/tests/Microsoft.Identity.Test.Common/Core/Helpers/ManagedIdentityTestUtil.cs index c6e0627d0c..1283c66ad5 100644 --- a/tests/Microsoft.Identity.Test.Common/Core/Helpers/ManagedIdentityTestUtil.cs +++ b/tests/Microsoft.Identity.Test.Common/Core/Helpers/ManagedIdentityTestUtil.cs @@ -62,6 +62,7 @@ public static void SetEnvironmentVariables(ManagedIdentitySource managedIdentity case ManagedIdentitySource.MachineLearning: Environment.SetEnvironmentVariable("MSI_ENDPOINT", endpoint); Environment.SetEnvironmentVariable("MSI_SECRET", secret); + Environment.SetEnvironmentVariable("DEFAULT_IDENTITY_CLIENT_ID", "fake_DEFAULT_IDENTITY_CLIENT_ID"); break; } } diff --git a/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs b/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs index bde5093fd3..7f505a9f7c 100644 --- a/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs +++ b/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs @@ -359,7 +359,7 @@ public static void AddRegionDiscoveryMockHandler( }); } - public static void AddManagedIdentityMockHandler( + public static MockHttpMessageHandler AddManagedIdentityMockHandler( this MockHttpManager httpManager, string expectedUrl, string resource, @@ -383,18 +383,17 @@ public static void AddManagedIdentityMockHandler( MockHttpMessageHandler httpMessageHandler = BuildMockHandlerForManagedIdentitySource(managedIdentitySourceType, resource); - if (userAssignedIdentityId == UserAssignedIdentityId.ClientId) + if (managedIdentitySourceType == ManagedIdentitySource.MachineLearning) { - if (managedIdentitySourceType == ManagedIdentitySource.MachineLearning) - { - // For Machine Learning (App Service 2017), the param is "clientid" - httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityClientId2017, userAssignedId); - } - else - { - // For App Service 2019, Azure Arc, IMDS, etc., the param is "client_id" - httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityClientId, userAssignedId); - } + // For Machine Learning (App Service 2017), the client id param is "clientid" + // it will always be a query parameter, no matter the source type + // use env var for SAMI, passed-in userAssignedId for UAMI + httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityClientId2017, + userAssignedId == null ? + EnvironmentVariables.MachineLearningDefaultClientId : userAssignedId); + } else if (userAssignedIdentityId == UserAssignedIdentityId.ClientId) { + // For App Service 2019, Azure Arc, IMDS, etc., the param is "client_id" + httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityClientId, userAssignedId); } if (userAssignedIdentityId == UserAssignedIdentityId.ResourceId) @@ -414,6 +413,8 @@ public static void AddManagedIdentityMockHandler( httpMessageHandler.ExpectedUrl = expectedUrl; httpManager.AddMockHandler(httpMessageHandler); + + return httpMessageHandler; } private static MockHttpMessageHandler BuildMockHandlerForManagedIdentitySource(ManagedIdentitySource managedIdentitySourceType, string resource) diff --git a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs index a63c469b17..e20b22e5b5 100644 --- a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs @@ -3,12 +3,11 @@ using System; using System.Globalization; -using System.Net; using System.Threading.Tasks; using Microsoft.Identity.Client; using Microsoft.Identity.Client.AppConfig; +using Microsoft.Identity.Client.Internal; using Microsoft.Identity.Client.ManagedIdentity; -using Microsoft.Identity.Test.Common; using Microsoft.Identity.Test.Common.Core.Helpers; using Microsoft.Identity.Test.Common.Core.Mocks; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -20,6 +19,82 @@ namespace Microsoft.Identity.Test.Unit.ManagedIdentityTests public class MachineLearningTests : TestBase { private const string MachineLearning = "Machine learning"; + private const string MachineLearningEndpoint = "http://localhost:7071/msi/token"; + internal const string Resource = "https://management.azure.com"; + + [DataTestMethod] + [DataRow(null, null)] // SAMI + [DataRow(TestConstants.ClientId, UserAssignedIdentityId.ClientId)] // UAMI + public async Task MachineLearningUserAssignedHappyPathAndHasCorrectClientIdQueryParameterAsync( + string userAssignedId, + UserAssignedIdentityId userAssignedIdentityId) + { + using (new EnvVariableContext()) + using (var httpManager = new MockHttpManager()) + { + SetEnvironmentVariables(ManagedIdentitySource.MachineLearning, MachineLearningEndpoint); + + ManagedIdentityId managedIdentityId = userAssignedId == null + ? ManagedIdentityId.SystemAssigned + : ManagedIdentityId.WithUserAssignedClientId(userAssignedId); + ManagedIdentityApplicationBuilder miBuilder = ManagedIdentityApplicationBuilder.Create(managedIdentityId) + .WithHttpManager(httpManager); + + IManagedIdentityApplication mi = miBuilder.Build(); + + // Disabling shared cache options to avoid cross test pollution. + miBuilder.Config.AccessorOptions = null; + + MockHttpMessageHandler mockHandler = httpManager.AddManagedIdentityMockHandler( + MachineLearningEndpoint, + Resource, + MockHelpers.GetMsiSuccessfulResponse(), + ManagedIdentitySource.MachineLearning, + userAssignedId: userAssignedId, + userAssignedIdentityId); + + AuthenticationResult result = await mi.AcquireTokenForManagedIdentity(Resource).ExecuteAsync().ConfigureAwait(false); + + Assert.IsNotNull(result); + Assert.IsNotNull(result.AccessToken); + + // Verify query parameter is "clientid" and not "client_id" + Assert.IsTrue(mockHandler.ExpectedQueryParams.ContainsKey(Constants.ManagedIdentityClientId2017), "Query parameter should use 'clientid' and not 'client_id'"); + + // Verify the clientid value based on identity type + string expectedClientId = userAssignedId ?? EnvironmentVariables.MachineLearningDefaultClientId; + Assert.AreEqual(expectedClientId, mockHandler.ExpectedQueryParams[Constants.ManagedIdentityClientId2017], + "Clientid value should match the provided user assigned ID for UAMI or environment variable for SAMI"); + } + } + + [DataTestMethod] + [DataRow(TestConstants.MiResourceId, UserAssignedIdentityId.ResourceId)] + [DataRow(TestConstants.MiResourceId, UserAssignedIdentityId.ObjectId)] + public async Task MachineLearningUserAssignedNonClientIdThrowsAsync( + string userAssignedId, + UserAssignedIdentityId userAssignedIdentityId) + { + using (new EnvVariableContext()) + using (var httpManager = new MockHttpManager()) + { + SetEnvironmentVariables(ManagedIdentitySource.MachineLearning, MachineLearningEndpoint); + + ManagedIdentityApplicationBuilder miBuilder = CreateMIABuilder(userAssignedId, userAssignedIdentityId); + miBuilder + .WithHttpManager(httpManager); + + IManagedIdentityApplication mi = miBuilder.Build(); + + MsalServiceException ex = await Assert.ThrowsExceptionAsync(async () => + await mi.AcquireTokenForManagedIdentity(Resource) + .ExecuteAsync().ConfigureAwait(false)).ConfigureAwait(false); + + Assert.IsNotNull(ex); + Assert.AreEqual(ManagedIdentitySource.MachineLearning.ToString(), ex.AdditionalExceptionData[MsalException.ManagedIdentitySource]); + Assert.AreEqual(MsalError.InvalidManagedIdentityIdType, ex.ErrorCode); + } + } [TestMethod] public async Task MachineLearningTestsInvalidEndpointAsync() @@ -29,13 +104,13 @@ public async Task MachineLearningTestsInvalidEndpointAsync() { SetEnvironmentVariables(ManagedIdentitySource.MachineLearning, "127.0.0.1:41564/msi/token"); - var miBuilder = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.SystemAssigned) + ManagedIdentityApplicationBuilder miBuilder = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.SystemAssigned) .WithHttpManager(httpManager); // Disabling shared cache options to avoid cross test pollution. miBuilder.Config.AccessorOptions = null; - var mi = miBuilder.Build(); + IManagedIdentityApplication mi = miBuilder.Build(); MsalServiceException ex = await Assert.ThrowsExceptionAsync(async () => await mi.AcquireTokenForManagedIdentity(ManagedIdentityTests.Resource) diff --git a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ManagedIdentityTests.cs b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ManagedIdentityTests.cs index d8d385e848..d4dba3501e 100644 --- a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ManagedIdentityTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ManagedIdentityTests.cs @@ -127,8 +127,6 @@ public async Task ManagedIdentityHappyPathAsync( [DataRow(ServiceFabricEndpoint, ManagedIdentitySource.ServiceFabric, TestConstants.MiResourceId, UserAssignedIdentityId .ResourceId)] [DataRow(ServiceFabricEndpoint, ManagedIdentitySource.ServiceFabric, TestConstants.MiResourceId, UserAssignedIdentityId.ObjectId)] [DataRow(MachineLearningEndpoint, ManagedIdentitySource.MachineLearning, TestConstants.ClientId, UserAssignedIdentityId.ClientId)] - [DataRow(MachineLearningEndpoint, ManagedIdentitySource.MachineLearning, TestConstants.MiResourceId, UserAssignedIdentityId.ResourceId)] - [DataRow(MachineLearningEndpoint, ManagedIdentitySource.MachineLearning, TestConstants.MiResourceId, UserAssignedIdentityId.ObjectId)] public async Task ManagedIdentityUserAssignedHappyPathAsync( string endpoint, ManagedIdentitySource managedIdentitySource, From d6eb37ee6d215a9ea7e670454f3c990c65759315 Mon Sep 17 00:00:00 2001 From: Robbie Ginsburg Date: Wed, 18 Jun 2025 07:46:13 -0400 Subject: [PATCH 2/6] unshipped changes --- .../PublicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../PublicApi/net472/PublicAPI.Unshipped.txt | 2 +- .../PublicApi/net8.0-android/PublicAPI.Unshipped.txt | 1 + .../PublicApi/net8.0-ios/PublicAPI.Unshipped.txt | 1 + .../PublicApi/net8.0/PublicAPI.Unshipped.txt | 2 +- .../PublicApi/netstandard2.0/PublicAPI.Unshipped.txt | 1 + 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt index 8b13789179..bfda2c78d8 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt @@ -1 +1 @@ - +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt index 8b13789179..bfda2c78d8 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt @@ -1 +1 @@ - +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt index e69de29bb2..bfda2c78d8 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt index e69de29bb2..bfda2c78d8 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt index 8b13789179..bfda2c78d8 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ - +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..bfda2c78d8 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string From df0a5b3950044758681b9e84b58fe1124285d395 Mon Sep 17 00:00:00 2001 From: Robbie Ginsburg Date: Mon, 30 Jun 2025 16:59:25 -0400 Subject: [PATCH 3/6] Added error type for missing env var --- .../MachineLearningManagedIdentitySource.cs | 14 +++++++++++++- src/client/Microsoft.Identity.Client/MsalError.cs | 5 +++++ .../PublicApi/net462/PublicAPI.Unshipped.txt | 1 + .../PublicApi/net472/PublicAPI.Unshipped.txt | 1 + .../net8.0-android/PublicAPI.Unshipped.txt | 1 + .../PublicApi/net8.0-ios/PublicAPI.Unshipped.txt | 1 + .../PublicApi/net8.0/PublicAPI.Unshipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + 8 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs index 9eca8bca41..dab5c10404 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs @@ -79,8 +79,20 @@ protected override ManagedIdentityRequest CreateRequest(string resource) { case AppConfig.ManagedIdentityIdType.SystemAssigned: _requestContext.Logger.Info("[Managed Identity] Adding system assigned client id to the request."); + + // this environment variable is always set in an Azure Machine Learning source, but check if null just in case + if (EnvironmentVariables.MachineLearningDefaultClientId == null) + { + throw MsalServiceExceptionFactory.CreateManagedIdentityException( + MsalError.InvalidManagedIdentityIdType, + "The DEFAULT_IDENTITY_CLIENT_ID environment variable is null.", + null, // configuration error + ManagedIdentitySource.MachineLearning, + null); // statusCode is null in this case + } + // Use the new 2017 constant for older ML-based environment - request.QueryParameters[Constants.ManagedIdentityClientId2017] = EnvironmentVariables.MachineLearningDefaultClientId; // this environment variable is always set in an Azure Machine Learning source + request.QueryParameters[Constants.ManagedIdentityClientId2017] = EnvironmentVariables.MachineLearningDefaultClientId; break; case AppConfig.ManagedIdentityIdType.ClientId: diff --git a/src/client/Microsoft.Identity.Client/MsalError.cs b/src/client/Microsoft.Identity.Client/MsalError.cs index 861d8ef0c3..a13974c616 100644 --- a/src/client/Microsoft.Identity.Client/MsalError.cs +++ b/src/client/Microsoft.Identity.Client/MsalError.cs @@ -1110,6 +1110,11 @@ public static class MsalError /// public const string InvalidManagedIdentityIdType = "invalid_managed_identity_id_type"; + /// + /// The managed identity is missing a required environment variable. + /// + public const string MissingManagedIdentityEnvVar = "missing_managed_identity_env_var"; + /// /// Managed Identity error response was received. /// diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt index bfda2c78d8..50d9f12956 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string +const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt index bfda2c78d8..50d9f12956 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string +const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt index bfda2c78d8..50d9f12956 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string +const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt index bfda2c78d8..50d9f12956 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string +const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt index bfda2c78d8..50d9f12956 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string +const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string diff --git a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt index bfda2c78d8..50d9f12956 100644 --- a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string +const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string From 7e5b1624eb2ba2b3f65e55c499827fe373eebc6c Mon Sep 17 00:00:00 2001 From: Robbie Ginsburg Date: Tue, 1 Jul 2025 16:54:36 -0400 Subject: [PATCH 4/6] Implemented feedback and improved code --- .../MachineLearningManagedIdentitySource.cs | 12 ++-------- .../Core/Mocks/MockHttpManagerExtensions.cs | 24 +++++++++++-------- .../MachineLearningTests.cs | 4 ++-- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs index dab5c10404..fa82e355fc 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs @@ -46,20 +46,12 @@ private static bool TryValidateEnvVars(string msiEndpoint, ILoggerAdapter logger } catch (FormatException ex) { - string errorMessage = string.Format( - CultureInfo.InvariantCulture, - MsalErrorMessage.ManagedIdentityEndpointInvalidUriError, - "MSI_ENDPOINT", msiEndpoint, "Machine learning"); - - // Use the factory to create and throw the exception - var exception = MsalServiceExceptionFactory.CreateManagedIdentityException( + throw MsalServiceExceptionFactory.CreateManagedIdentityException( MsalError.InvalidManagedIdentityEndpoint, - errorMessage, + UnsupportedIdTypeError, ex, ManagedIdentitySource.MachineLearning, null); // statusCode is null in this case - - throw exception; } logger.Info($"[Managed Identity] Environment variables validation passed for machine learning managed identity. Endpoint URI: {endpointUri}. Creating machine learning managed identity."); diff --git a/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs b/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs index 2cfd9441a5..38bd9239e3 100644 --- a/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs +++ b/tests/Microsoft.Identity.Test.Common/Core/Mocks/MockHttpManagerExtensions.cs @@ -388,25 +388,29 @@ public static MockHttpMessageHandler AddManagedIdentityMockHandler( // For Machine Learning (App Service 2017), the client id param is "clientid" // it will always be a query parameter, no matter the source type // use env var for SAMI, passed-in userAssignedId for UAMI - httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityClientId2017, - userAssignedId == null ? - EnvironmentVariables.MachineLearningDefaultClientId : userAssignedId); - } else if (userAssignedIdentityId == UserAssignedIdentityId.ClientId) { + httpMessageHandler.ExpectedQueryParams.Add( + Constants.ManagedIdentityClientId2017, + userAssignedId ?? EnvironmentVariables.MachineLearningDefaultClientId); + } + else if (userAssignedIdentityId == UserAssignedIdentityId.ClientId) + { // For App Service 2019, Azure Arc, IMDS, etc., the param is "client_id" - httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityClientId, userAssignedId); + httpMessageHandler.ExpectedQueryParams.Add( + Constants.ManagedIdentityClientId, + userAssignedId); } - - if (userAssignedIdentityId == UserAssignedIdentityId.ResourceId) + else if (userAssignedIdentityId == UserAssignedIdentityId.ResourceId) { httpMessageHandler.ExpectedQueryParams.Add( managedIdentitySourceType == ManagedIdentitySource.Imds ? Constants.ManagedIdentityResourceIdImds : Constants.ManagedIdentityResourceId, userAssignedId); } - - if (userAssignedIdentityId == UserAssignedIdentityId.ObjectId) + else if (userAssignedIdentityId == UserAssignedIdentityId.ObjectId) { - httpMessageHandler.ExpectedQueryParams.Add(Constants.ManagedIdentityObjectId, userAssignedId); + httpMessageHandler.ExpectedQueryParams.Add( + Constants.ManagedIdentityObjectId, + userAssignedId); } httpMessageHandler.ResponseMessage = responseMessage; diff --git a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs index e20b22e5b5..9cfe4970bc 100644 --- a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs @@ -104,13 +104,13 @@ public async Task MachineLearningTestsInvalidEndpointAsync() { SetEnvironmentVariables(ManagedIdentitySource.MachineLearning, "127.0.0.1:41564/msi/token"); - ManagedIdentityApplicationBuilder miBuilder = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.SystemAssigned) + var miBuilder = ManagedIdentityApplicationBuilder.Create(ManagedIdentityId.SystemAssigned) .WithHttpManager(httpManager); // Disabling shared cache options to avoid cross test pollution. miBuilder.Config.AccessorOptions = null; - IManagedIdentityApplication mi = miBuilder.Build(); + var mi = miBuilder.Build(); MsalServiceException ex = await Assert.ThrowsExceptionAsync(async () => await mi.AcquireTokenForManagedIdentity(ManagedIdentityTests.Resource) From 0ae2c09524f7719372e4e7a75232590865f07f8f Mon Sep 17 00:00:00 2001 From: Robbie Ginsburg Date: Tue, 1 Jul 2025 16:57:03 -0400 Subject: [PATCH 5/6] improvements --- .../MachineLearningManagedIdentitySource.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs index fa82e355fc..02b11bc930 100644 --- a/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs +++ b/src/client/Microsoft.Identity.Client/ManagedIdentity/MachineLearningManagedIdentitySource.cs @@ -46,9 +46,14 @@ private static bool TryValidateEnvVars(string msiEndpoint, ILoggerAdapter logger } catch (FormatException ex) { + string errorMessage = string.Format( + CultureInfo.InvariantCulture, + MsalErrorMessage.ManagedIdentityEndpointInvalidUriError, + "MSI_ENDPOINT", msiEndpoint, "Machine learning"); + throw MsalServiceExceptionFactory.CreateManagedIdentityException( MsalError.InvalidManagedIdentityEndpoint, - UnsupportedIdTypeError, + errorMessage, ex, ManagedIdentitySource.MachineLearning, null); // statusCode is null in this case @@ -94,20 +99,12 @@ protected override ManagedIdentityRequest CreateRequest(string resource) break; default: - string errorMessage = string.Format( - CultureInfo.InvariantCulture, - MsalErrorMessage.ManagedIdentityInvalidIdType, - "client id is", - MachineLearning); - - var exception = MsalServiceExceptionFactory.CreateManagedIdentityException( + throw MsalServiceExceptionFactory.CreateManagedIdentityException( MsalError.InvalidManagedIdentityIdType, - errorMessage, + UnsupportedIdTypeError, null, // configuration error ManagedIdentitySource.MachineLearning, null); // statusCode is null in this case - - throw exception; } return request; From 0a74b6f52473d5ef50129957267b822d1f1cc939 Mon Sep 17 00:00:00 2001 From: Robbie Ginsburg Date: Tue, 1 Jul 2025 17:11:01 -0400 Subject: [PATCH 6/6] fixed broken unit tests --- .../ManagedIdentityTests/MachineLearningTests.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs index 9cfe4970bc..137be702a3 100644 --- a/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/MachineLearningTests.cs @@ -37,14 +37,14 @@ public async Task MachineLearningUserAssignedHappyPathAndHasCorrectClientIdQuery ManagedIdentityId managedIdentityId = userAssignedId == null ? ManagedIdentityId.SystemAssigned : ManagedIdentityId.WithUserAssignedClientId(userAssignedId); - ManagedIdentityApplicationBuilder miBuilder = ManagedIdentityApplicationBuilder.Create(managedIdentityId) + var miBuilder = ManagedIdentityApplicationBuilder.Create(managedIdentityId) .WithHttpManager(httpManager); - IManagedIdentityApplication mi = miBuilder.Build(); - // Disabling shared cache options to avoid cross test pollution. miBuilder.Config.AccessorOptions = null; + var mi = miBuilder.Build(); + MockHttpMessageHandler mockHandler = httpManager.AddManagedIdentityMockHandler( MachineLearningEndpoint, Resource, @@ -80,11 +80,13 @@ public async Task MachineLearningUserAssignedNonClientIdThrowsAsync( { SetEnvironmentVariables(ManagedIdentitySource.MachineLearning, MachineLearningEndpoint); - ManagedIdentityApplicationBuilder miBuilder = CreateMIABuilder(userAssignedId, userAssignedIdentityId); - miBuilder + var miBuilder = CreateMIABuilder(userAssignedId, userAssignedIdentityId) .WithHttpManager(httpManager); - IManagedIdentityApplication mi = miBuilder.Build(); + // Disabling shared cache options to avoid cross test pollution. + miBuilder.Config.AccessorOptions = null; + + var mi = miBuilder.Build(); MsalServiceException ex = await Assert.ThrowsExceptionAsync(async () => await mi.AcquireTokenForManagedIdentity(Resource)