diff --git a/sdk/identity/Azure.Identity/src/DefaultAzureCredentialOptions.cs b/sdk/identity/Azure.Identity/src/DefaultAzureCredentialOptions.cs index f60bde8aaa528..9fb2b49371c74 100644 --- a/sdk/identity/Azure.Identity/src/DefaultAzureCredentialOptions.cs +++ b/sdk/identity/Azure.Identity/src/DefaultAzureCredentialOptions.cs @@ -15,7 +15,7 @@ public class DefaultAzureCredentialOptions : TokenCredentialOptions /// . The default is null and will authenticate users to their default tenant. /// The value can also be set by setting the environment variable AZURE_TENANT_ID. /// - public string InteractiveBrowserTenantId { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); + public string InteractiveBrowserTenantId { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); /// /// Specifies the tenant id of the preferred authentication account, to be retrieved from the shared token cache for single sign on authentication with @@ -25,21 +25,21 @@ public class DefaultAzureCredentialOptions : TokenCredentialOptions /// If multiple accounts are found in the shared token cache and no value is specified, or the specified value matches no accounts in /// the cache the SharedTokenCacheCredential will not be used for authentication. /// - public string SharedTokenCacheTenantId { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); + public string SharedTokenCacheTenantId { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); /// /// The tenant id of the user to authenticate, in the case the authenticates through, the /// . The default is null and will authenticate users to their default tenant. /// The value can also be set by setting the environment variable AZURE_TENANT_ID. /// - public string VisualStudioTenantId { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); + public string VisualStudioTenantId { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); /// /// The tenant id of the user to authenticate, in the case the authenticates through, the /// . The default is null and will authenticate users to their default tenant. /// The value can also be set by setting the environment variable AZURE_TENANT_ID. /// - public string VisualStudioCodeTenantId { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); + public string VisualStudioCodeTenantId { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.TenantId); /// /// Specifies the preferred authentication account to be retrieved from the shared token cache for single sign on authentication with @@ -49,12 +49,12 @@ public class DefaultAzureCredentialOptions : TokenCredentialOptions /// If multiple accounts are found in the shared token cache and no value is specified, or the specified value matches no accounts in /// the cache the SharedTokenCacheCredential will not be used for authentication. /// - public string SharedTokenCacheUsername { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.Username); + public string SharedTokenCacheUsername { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.Username); /// /// Specifies the client id of the azure ManagedIdentity in the case of user assigned identity. /// - public string ManagedIdentityClientId { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.ClientId); + public string ManagedIdentityClientId { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.ClientId); /// /// Specifies whether the will be excluded from the authentication flow. Setting to true disables reading @@ -94,10 +94,5 @@ public class DefaultAzureCredentialOptions : TokenCredentialOptions /// Specifies whether the will be excluded from the authentication flow. /// public bool ExcludeVisualStudioCodeCredential { get; set; } - - private static string GetNonEmptyStringOrNull(string str) - { - return !string.IsNullOrEmpty(str) ? str : null; - } } } diff --git a/sdk/identity/Azure.Identity/src/EnvironmentVariables.cs b/sdk/identity/Azure.Identity/src/EnvironmentVariables.cs index 8c68e789ea638..680438e20a842 100644 --- a/sdk/identity/Azure.Identity/src/EnvironmentVariables.cs +++ b/sdk/identity/Azure.Identity/src/EnvironmentVariables.cs @@ -26,5 +26,10 @@ internal class EnvironmentVariables public static string ProgramFilesX86 => Environment.GetEnvironmentVariable("ProgramFiles(x86)"); public static string ProgramFiles => Environment.GetEnvironmentVariable("ProgramFiles"); public static string AuthorityHost => Environment.GetEnvironmentVariable("AZURE_AUTHORITY_HOST"); + + public static string GetNonEmptyStringOrNull(string str) + { + return !string.IsNullOrEmpty(str) ? str : null; + } } } diff --git a/sdk/identity/Azure.Identity/src/ManagedIdentityClient.cs b/sdk/identity/Azure.Identity/src/ManagedIdentityClient.cs index 72d8adc067a62..82b5a2aeaee0b 100644 --- a/sdk/identity/Azure.Identity/src/ManagedIdentityClient.cs +++ b/sdk/identity/Azure.Identity/src/ManagedIdentityClient.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Azure.Core; @@ -27,13 +26,13 @@ public ManagedIdentityClient(CredentialPipeline pipeline, string clientId = null public ManagedIdentityClient(ManagedIdentityClientOptions options) { _options = options; - ClientId = options.ClientId; + ClientId = options.ClientId ?? EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.ClientId); Pipeline = options.Pipeline; } internal CredentialPipeline Pipeline { get; } - protected string ClientId { get; } + protected internal string ClientId { get; } public virtual async ValueTask AuthenticateAsync(bool async, TokenRequestContext context, CancellationToken cancellationToken) { diff --git a/sdk/identity/Azure.Identity/src/ManagedIdentityClientOptions.cs b/sdk/identity/Azure.Identity/src/ManagedIdentityClientOptions.cs index 9ca051cac54d1..9622929506914 100644 --- a/sdk/identity/Azure.Identity/src/ManagedIdentityClientOptions.cs +++ b/sdk/identity/Azure.Identity/src/ManagedIdentityClientOptions.cs @@ -7,7 +7,7 @@ internal class ManagedIdentityClientOptions { public TokenCredentialOptions Options { get; set; } - public string ClientId { get; set; } + public string ClientId { get; set; } = EnvironmentVariables.GetNonEmptyStringOrNull(EnvironmentVariables.ClientId); public bool PreserveTransport { get; set; } diff --git a/sdk/identity/Azure.Identity/tests/ManagedIdentityClientOptionsTests.cs b/sdk/identity/Azure.Identity/tests/ManagedIdentityClientOptionsTests.cs new file mode 100644 index 0000000000000..1ee4fd5ee4179 --- /dev/null +++ b/sdk/identity/Azure.Identity/tests/ManagedIdentityClientOptionsTests.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Identity.Tests; +using NUnit.Framework; + +namespace Azure.Identity.Tests +{ + public class ManagedIdentityClientOptionsTests + { + public const string ExplicitClientId = "1234"; + public const string ClientIdFromEnvironment = "4567"; + + [Test] + public void ClientIdIsReadFromEnvironmentVariableWhenAvailable( + [Values(null, ExplicitClientId)] string explicitClientId, + [Values(null, ClientIdFromEnvironment)] string clientIdFromEnvironment) + { + using (new TestEnvVar(new () + { + { "AZURE_CLIENT_ID", clientIdFromEnvironment } + })) + { + var options = new ManagedIdentityClientOptions(); + if (explicitClientId != null) + { + options.ClientId = explicitClientId; + } + + string expectedClientId = explicitClientId switch + { + null when clientIdFromEnvironment is null => null, + null when clientIdFromEnvironment is not null => clientIdFromEnvironment, + _ => explicitClientId, + }; + + Assert.That(options.ClientId, Is.EqualTo(expectedClientId)); + } + } + } +} diff --git a/sdk/identity/Azure.Identity/tests/ManagedIdentityClientTests.cs b/sdk/identity/Azure.Identity/tests/ManagedIdentityClientTests.cs new file mode 100644 index 0000000000000..136d55ecbc53e --- /dev/null +++ b/sdk/identity/Azure.Identity/tests/ManagedIdentityClientTests.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Azure.Identity.Tests; +using NUnit.Framework; + +namespace Azure.Identity.Tests +{ + public class ManagedIdentityClientTests + { + public const string ClientIdFromCtor = "1234"; + public const string ClientIdFromEnvironment = "4567"; + + [Test] + public void ClientIdIsReadFromEnvironmentVariableWhenAvailable( + [Values(null, ClientIdFromCtor)] string clientIdFromCtor, + [Values(null, ClientIdFromEnvironment)] string clientIdFromEnvironment) + { + using (new TestEnvVar(new () + { + { "AZURE_CLIENT_ID", clientIdFromEnvironment }})) + { + var client = new ManagedIdentityClient(default, clientIdFromCtor); + + string expectedClientId = clientIdFromCtor switch + { + null when clientIdFromEnvironment is null => null, + null when clientIdFromEnvironment is not null => clientIdFromEnvironment, + _ => clientIdFromCtor, + }; + + Assert.That(client.ClientId, Is.EqualTo(expectedClientId)); + } + } + } +}