// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Net; using Azure.Core; namespace Azure.Identity { /// /// Options to configure the authentication flow and requests made to Azure Identity services. /// public class DefaultAzureCredentialOptions : TokenCredentialOptions, ISupportsDisableInstanceDiscovery, ISupportsAdditionallyAllowedTenants { private struct UpdateTracker { private bool _updated; private T _value; public UpdateTracker(T initialValue) { _value = initialValue; _updated = false; } public T Value { get => _value; set { _value = value; _updated = true; } } public bool Updated => _updated; } private UpdateTracker _tenantId = new UpdateTracker(EnvironmentVariables.TenantId); private UpdateTracker _interactiveBrowserTenantId = new UpdateTracker(EnvironmentVariables.TenantId); private UpdateTracker _sharedTokenCacheTenantId = new UpdateTracker(EnvironmentVariables.TenantId); private UpdateTracker _visualStudioTenantId = new UpdateTracker(EnvironmentVariables.TenantId); private UpdateTracker _visualStudioCodeTenantId = new UpdateTracker(EnvironmentVariables.TenantId); /// /// The ID of the tenant to which the credential will authenticate by default. If not specified, the credential will authenticate to any requested tenant, and will default to the tenant to which the chosen authentication method was originally authenticated. /// public string TenantId { get => _tenantId.Value; set { if (_interactiveBrowserTenantId.Updated && _tenantId.Value != _interactiveBrowserTenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and InteractiveBrowserTenantId. TenantId is preferred, and is functionally equivalent. InteractiveBrowserTenantId exists only to provide backwards compatibility."); } if (_sharedTokenCacheTenantId.Updated && _tenantId.Value != _sharedTokenCacheTenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and SharedTokenCacheTenantId. TenantId is preferred, and is functionally equivalent. SharedTokenCacheTenantId exists only to provide backwards compatibility."); } if (_visualStudioTenantId.Updated && _tenantId.Value != _visualStudioTenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and VisualStudioTenantId. TenantId is preferred, and is functionally equivalent. VisualStudioTenantId exists only to provide backwards compatibility."); } if (_visualStudioCodeTenantId.Updated && _tenantId.Value != _visualStudioCodeTenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and VisualStudioCodeTenantId. TenantId is preferred, and is functionally equivalent. VisualStudioCodeTenantId exists only to provide backwards compatibility."); } _tenantId.Value = value; _interactiveBrowserTenantId.Value = value; _sharedTokenCacheTenantId.Value = value; _visualStudioCodeTenantId.Value = value; _visualStudioTenantId.Value = value; } } /// /// 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. /// [EditorBrowsable(EditorBrowsableState.Never)] public string InteractiveBrowserTenantId { get => _interactiveBrowserTenantId.Value; set { if (_tenantId.Updated && value != _tenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and InteractiveBrowserTenantId. TenantId is preferred, and is functionally equivalent. InteractiveBrowserTenantId exists only to provide backwards compatibility."); } _interactiveBrowserTenantId.Value = value; } } /// /// Specifies the tenant id of the preferred authentication account, to be retrieved from the shared token cache for single sign on authentication with /// development tools, in the case multiple accounts are found in the shared token. /// /// /// 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. /// [EditorBrowsable(EditorBrowsableState.Never)] public string SharedTokenCacheTenantId { get => _sharedTokenCacheTenantId.Value; set { if (_tenantId.Updated && value != _tenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and SharedTokenCacheTenantId. TenantId is preferred, and is functionally equivalent. SharedTokenCacheTenantId exists only to provide backwards compatibility."); } _sharedTokenCacheTenantId.Value = value; } } /// /// 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. /// [EditorBrowsable(EditorBrowsableState.Never)] public string VisualStudioTenantId { get => _visualStudioTenantId.Value; set { if (_tenantId.Updated && value != _tenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and VisualStudioTenantId. TenantId is preferred, and is functionally equivalent. VisualStudioTenantId exists only to provide backwards compatibility."); } _visualStudioTenantId.Value = value; } } /// /// 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. /// [EditorBrowsable(EditorBrowsableState.Never)] public string VisualStudioCodeTenantId { get => _visualStudioCodeTenantId.Value; set { if (_tenantId.Updated && value != _tenantId.Value) { throw new InvalidOperationException("Applications should not set both TenantId and VisualStudioCodeTenantId. TenantId is preferred, and is functionally equivalent. VisualStudioCodeTenantId exists only to provide backwards compatibility."); } _visualStudioCodeTenantId.Value = value; } } /// /// Specifies tenants in addition to the specified for which the credential may acquire tokens. /// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant the logged in account can access. /// If no value is specified for , this option will have no effect on that authentication method, and the credential will acquire tokens for any requested tenant when using that method. /// This value can also be set by setting the environment variable AZURE_ADDITIONALLY_ALLOWED_TENANTS. /// public IList AdditionallyAllowedTenants { get; internal set; } = EnvironmentVariables.AdditionallyAllowedTenants; /// /// Specifies the preferred authentication account to be retrieved from the shared token cache for single sign on authentication with /// development tools. In the case multiple accounts are found in the shared token. /// /// /// 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; } = EnvironmentVariables.Username; /// /// Specifies the client id of the selected credential /// public string InteractiveBrowserCredentialClientId { get; set; } /// /// Specifies the client id of the application the workload identity will authenticate. /// public string WorkloadIdentityClientId { get; set; } = EnvironmentVariables.ClientId; /// /// Specifies the client ID of a user-assigned managed identity. If this value is configured, then should not be configured. /// /// /// If neither the nor the property is set, then a system-assigned managed identity is used. /// public string ManagedIdentityClientId { get; set; } = EnvironmentVariables.ClientId; /// /// Specifies the resource ID of a user-assigned managed identity. If this value is configured, then should not be configured. /// /// /// If neither the nor the property is set, then a system-assigned managed identity is used. /// public ResourceIdentifier ManagedIdentityResourceId { get; set; } /// /// Specifies timeout for credentials invoked via sub-process. e.g. Visual Studio, Azure CLI, Azure PowerShell. /// public TimeSpan? CredentialProcessTimeout { get; set; } = TimeSpan.FromSeconds(30); /// /// Specifies whether the will be excluded from the authentication flow. Setting to true disables reading /// authentication details from the process' environment variables. /// public bool ExcludeEnvironmentCredential { get; set; } /// /// Specifies whether the will be excluded from the authentication flow. Setting to true disables reading /// authentication details from the process' environment variables. /// public bool ExcludeWorkloadIdentityCredential { get; set; } /// /// Specifies whether the will be excluded from the authentication flow. /// Setting to true disables authenticating with managed identity endpoints. /// public bool ExcludeManagedIdentityCredential { get; set; } /// /// Specifies whether the will be excluded from the authentication flow. /// public bool ExcludeAzureDeveloperCliCredential { get; set; } /// /// Specifies whether the will be excluded from the authentication flow. /// Setting to true disables single sign on authentication with development tools which write to the shared token cache. /// The default is true. /// public bool ExcludeSharedTokenCacheCredential { get; set; } = true; /// /// Specifies whether the will be excluded from the authentication flow. /// Setting to true disables launching the default system browser to authenticate in development environments. /// The default is true. /// public bool ExcludeInteractiveBrowserCredential { get; set; } = true; /// /// Specifies whether the will be excluded from the authentication flow. /// public bool ExcludeAzureCliCredential { get; set; } /// /// Specifies whether the will be excluded from the authentication flow. /// public bool ExcludeVisualStudioCredential { get; set; } /// /// Specifies whether the will be excluded from the authentication flow. /// The default is true. /// public bool ExcludeVisualStudioCodeCredential { get; set; } = true; /// /// Specifies whether the will be excluded from the authentication flow. /// public bool ExcludeAzurePowerShellCredential { get; set; } /// public bool DisableInstanceDiscovery { get; set; } internal bool IsForceRefreshEnabled { get; set; } internal override T Clone<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>() { var clone = base.Clone(); if (clone is DefaultAzureCredentialOptions dacClone) { dacClone._tenantId = _tenantId; dacClone._interactiveBrowserTenantId = _interactiveBrowserTenantId; dacClone._sharedTokenCacheTenantId = _sharedTokenCacheTenantId; dacClone._visualStudioTenantId = _visualStudioTenantId; dacClone._visualStudioCodeTenantId = _visualStudioCodeTenantId; dacClone.SharedTokenCacheUsername = SharedTokenCacheUsername; dacClone.InteractiveBrowserCredentialClientId = InteractiveBrowserCredentialClientId; dacClone.WorkloadIdentityClientId = WorkloadIdentityClientId; dacClone.ManagedIdentityClientId = ManagedIdentityClientId; dacClone.ManagedIdentityResourceId = ManagedIdentityResourceId; dacClone.CredentialProcessTimeout = CredentialProcessTimeout; dacClone.ExcludeEnvironmentCredential = ExcludeEnvironmentCredential; dacClone.ExcludeWorkloadIdentityCredential = ExcludeWorkloadIdentityCredential; dacClone.ExcludeManagedIdentityCredential = ExcludeManagedIdentityCredential; dacClone.ExcludeAzureDeveloperCliCredential = ExcludeAzureDeveloperCliCredential; dacClone.ExcludeSharedTokenCacheCredential = ExcludeSharedTokenCacheCredential; dacClone.ExcludeInteractiveBrowserCredential = ExcludeInteractiveBrowserCredential; dacClone.ExcludeAzureCliCredential = ExcludeAzureCliCredential; dacClone.ExcludeVisualStudioCredential = ExcludeVisualStudioCredential; dacClone.ExcludeVisualStudioCodeCredential = ExcludeVisualStudioCodeCredential; dacClone.ExcludeAzurePowerShellCredential = ExcludeAzurePowerShellCredential; dacClone.IsForceRefreshEnabled = IsForceRefreshEnabled; } return clone; } } }