internal static TokenCredential CreateCredential()

in sdk/extensions/Microsoft.Extensions.Azure/src/Internal/ClientFactory.cs [94:302]


        internal static TokenCredential CreateCredential(IConfiguration configuration)
        {
            var credentialType = configuration["credential"];
            var clientId = configuration["clientId"];
            var tenantId = configuration["tenantId"];
            var serviceConnectionId = configuration["serviceConnectionId"];
            var resourceId = configuration["managedIdentityResourceId"];
            var objectId = configuration["managedIdentityObjectId"];
            var clientSecret = configuration["clientSecret"];
            var certificate = configuration["clientCertificate"];
            var certificateStoreName = configuration["clientCertificateStoreName"];
            var certificateStoreLocation = configuration["clientCertificateStoreLocation"];
            var systemAccessToken = configuration["systemAccessToken"];
            var additionallyAllowedTenants = configuration["additionallyAllowedTenants"];
            var tokenFilePath = configuration["tokenFilePath"];
            IEnumerable<string> additionallyAllowedTenantsList = null;
            if (!string.IsNullOrWhiteSpace(additionallyAllowedTenants))
            {
                // not relying on StringSplitOptions.RemoveEmptyEntries as we want to remove leading/trailing whitespace between entries
                additionallyAllowedTenantsList = additionallyAllowedTenants.Split(TenantDelimiter)
                    .Select(t => t.Trim())
                    .Where(t => t.Length > 0);
            }

            if (string.Equals(credentialType, "managedidentity", StringComparison.OrdinalIgnoreCase))
            {
                int idCount = 0;
                idCount += string.IsNullOrWhiteSpace(clientId) ? 0 : 1;
                idCount += string.IsNullOrWhiteSpace(resourceId) ? 0 : 1;
                idCount += string.IsNullOrWhiteSpace(objectId) ? 0 : 1;

                if (idCount > 1)
                {
                    throw new ArgumentException("Only one of either 'clientId', 'managedIdentityResourceId', or 'managedIdentityObjectId' can be specified for managed identity.");
                }

                if (!string.IsNullOrWhiteSpace(resourceId))
                {
                    return new ManagedIdentityCredential(new ResourceIdentifier(resourceId));
                }

                if (!string.IsNullOrWhiteSpace(objectId))
                {
                    return new ManagedIdentityCredential(ManagedIdentityId.FromUserAssignedObjectId(objectId));
                }

                return new ManagedIdentityCredential(clientId);
            }

            if (string.Equals(credentialType, "workloadidentity", StringComparison.OrdinalIgnoreCase))
            {
                // The WorkloadIdentityCredentialOptions object initialization populates its instance members
                // from the environment variables AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_FEDERATED_TOKEN_FILE
                var workloadIdentityOptions = new WorkloadIdentityCredentialOptions();
                if (!string.IsNullOrWhiteSpace(tenantId))
                {
                    workloadIdentityOptions.TenantId = tenantId;
                }

                if (!string.IsNullOrWhiteSpace(clientId))
                {
                    workloadIdentityOptions.ClientId = clientId;
                }

                if (!string.IsNullOrWhiteSpace(tokenFilePath))
                {
                    workloadIdentityOptions.TokenFilePath = tokenFilePath;
                }

                if (additionallyAllowedTenantsList != null)
                {
                    foreach (string tenant in additionallyAllowedTenantsList)
                    {
                        workloadIdentityOptions.AdditionallyAllowedTenants.Add(tenant);
                    }
                }

                if (!string.IsNullOrWhiteSpace(workloadIdentityOptions.TenantId) &&
                    !string.IsNullOrWhiteSpace(workloadIdentityOptions.ClientId) &&
                    !string.IsNullOrWhiteSpace(workloadIdentityOptions.TokenFilePath))
                {
                    return new WorkloadIdentityCredential(workloadIdentityOptions);
                }

                throw new ArgumentException("For workload identity, 'tenantId', 'clientId', and 'tokenFilePath' must be specified via environment variables or the configuration.");
            }

            if (string.Equals(credentialType, "azurepipelines", StringComparison.OrdinalIgnoreCase))
            {
                if (string.IsNullOrWhiteSpace(tenantId) ||
                    string.IsNullOrWhiteSpace(clientId) ||
                    string.IsNullOrWhiteSpace(serviceConnectionId) ||
                    string.IsNullOrWhiteSpace(systemAccessToken))
                {
                    throw new ArgumentException("For Azure Pipelines, 'tenantId', 'clientId', 'serviceConnectionId', and 'systemAccessToken' must be specified via the configuration.");
                }

                var options = new AzurePipelinesCredentialOptions();

                if (additionallyAllowedTenantsList != null)
                {
                    foreach (string tenant in additionallyAllowedTenantsList)
                    {
                        options.AdditionallyAllowedTenants.Add(tenant);
                    }
                }

                return new AzurePipelinesCredential(tenantId, clientId, serviceConnectionId, systemAccessToken, options);
            }

            if (!string.IsNullOrWhiteSpace(tenantId) &&
                !string.IsNullOrWhiteSpace(clientId) &&
                !string.IsNullOrWhiteSpace(clientSecret))
            {
                var options = new ClientSecretCredentialOptions();

                if (additionallyAllowedTenantsList != null)
                {
                    foreach (string tenant in additionallyAllowedTenantsList)
                    {
                        options.AdditionallyAllowedTenants.Add(tenant);
                    }
                }
                return new ClientSecretCredential(tenantId, clientId, clientSecret, options);
            }

            if (!string.IsNullOrWhiteSpace(tenantId) &&
                !string.IsNullOrWhiteSpace(clientId) &&
                !string.IsNullOrWhiteSpace(certificate))
            {
                StoreLocation storeLocation = StoreLocation.CurrentUser;

                if (!string.IsNullOrWhiteSpace(certificateStoreLocation))
                {
                    storeLocation = (StoreLocation)Enum.Parse(typeof(StoreLocation), certificateStoreLocation, true);
                }

                if (string.IsNullOrWhiteSpace(certificateStoreName))
                {
                    certificateStoreName = "MY"; // MY is the default used in X509Store
                }

                using var store = new X509Store(certificateStoreName, storeLocation);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificate, false);

                if (certs.Count == 0)
                {
                    throw new InvalidOperationException($"Unable to find a certificate with thumbprint '{certificate}'");
                }

                var options = new ClientCertificateCredentialOptions();

                if (additionallyAllowedTenantsList != null)
                {
                    foreach (string tenant in additionallyAllowedTenantsList)
                    {
                        options.AdditionallyAllowedTenants.Add(tenant);
                    }
                }
                var credential = new ClientCertificateCredential(tenantId, clientId, certs[0], options);

                store.Close();

                return credential;
            }

            // TODO: More logging

            if (!string.IsNullOrWhiteSpace(objectId))
            {
                throw new ArgumentException("'managedIdentityObjectId' is only supported when the credential type is 'managedidentity'.");
            }

            if (additionallyAllowedTenantsList != null
                || !string.IsNullOrWhiteSpace(tenantId)
                || !string.IsNullOrWhiteSpace(clientId)
                || !string.IsNullOrWhiteSpace(resourceId))
            {
                var options = new DefaultAzureCredentialOptions();

                if (additionallyAllowedTenantsList != null)
                {
                    foreach (string tenant in additionallyAllowedTenantsList)
                    {
                        options.AdditionallyAllowedTenants.Add(tenant);
                    }
                }

                if (!string.IsNullOrWhiteSpace(tenantId))
                {
                    options.TenantId = tenantId;
                }

                if (!string.IsNullOrWhiteSpace(clientId))
                {
                    options.ManagedIdentityClientId = clientId;
                }

                // validation that both clientId and ResourceId are not set happens in Azure.Identity
                if (!string.IsNullOrWhiteSpace(resourceId))
                {
                    options.ManagedIdentityResourceId = new ResourceIdentifier(resourceId);
                }

                return new DefaultAzureCredential(options);
            }
            return null;
        }