/// <summary>
        ///     Gets a valid token using a Service Principal or a Managed Identity
        /// </summary>
        public static async Task <TokenCredentials> GetTokenCredentialsAsync(string resource, string tenantId, AzureAuthenticationInfo authenticationInfo, System.Uri azureAuthorityHost)
        {
            Guard.NotNullOrWhitespace(resource, nameof(resource));
            Guard.NotNullOrWhitespace(tenantId, nameof(tenantId));
            Guard.NotNull(authenticationInfo, nameof(authenticationInfo));

            TokenCredential tokenCredential;

            var tokenCredentialOptions = new TokenCredentialOptions {
                AuthorityHost = azureAuthorityHost
            };

            switch (authenticationInfo.Mode)
            {
            case AuthenticationMode.ServicePrincipal:
                tokenCredential = new ClientSecretCredential(tenantId, authenticationInfo.IdentityId, authenticationInfo.Secret, tokenCredentialOptions);
                break;

            case AuthenticationMode.UserAssignedManagedIdentity:
                tokenCredential = new ManagedIdentityCredential(authenticationInfo.IdentityId, tokenCredentialOptions);
                break;

            case AuthenticationMode.SystemAssignedManagedIdentity:
                tokenCredential = new ManagedIdentityCredential(options: tokenCredentialOptions);
                break;

            default:
                tokenCredential = new DefaultAzureCredential();
                break;
            }

            // When you reaching an endpoint, using an impersonate identity, the only endpoint available is always '/.default'
            // MSAL add the './default' string to your resource request behind the scene.
            // We have to do it here, since we are at a lower level(and we are not using MSAL; by the way)
            if (!resource.ToLowerInvariant().EndsWith("/.default"))
            {
                if (!resource.EndsWith("/"))
                {
                    resource += "/";
                }

                resource += ".default";
            }

            var accessToken = await tokenCredential.GetTokenAsync(new TokenRequestContext(new[] { resource }), default);

            return(new TokenCredentials(accessToken.Token));
        }
        private static AzureCredentials GetServicePrincipleCredentials(AzureEnvironment azureCloud, string tenantId, AzureAuthenticationInfo azureAuthenticationInfo, AzureCredentialsFactory azureCredentialsFactory)
        {
            if (string.IsNullOrWhiteSpace(azureAuthenticationInfo.IdentityId))
            {
                throw new AuthenticationException("No identity was configured for service principle authentication");
            }

            if (string.IsNullOrWhiteSpace(azureAuthenticationInfo.Secret))
            {
                throw new AuthenticationException("No identity was configured for service principle authentication");
            }

            return(azureCredentialsFactory.FromServicePrincipal(azureAuthenticationInfo.IdentityId, azureAuthenticationInfo.Secret, tenantId, azureCloud));
        }
        private static AzureCredentials GetUserAssignedManagedIdentityCredentials(AzureEnvironment azureCloud, string tenantId, AzureAuthenticationInfo azureAuthenticationInfo, AzureCredentialsFactory azureCredentialsFactory)
        {
            if (string.IsNullOrWhiteSpace(azureAuthenticationInfo.IdentityId))
            {
                throw new AuthenticationException("No identity was configured for user-assigned managed identity");
            }

            return(azureCredentialsFactory.FromUserAssigedManagedServiceIdentity(azureAuthenticationInfo.IdentityId, MSIResourceType.VirtualMachine, azureCloud, tenantId));
        }
        public static AzureCredentials CreateAzureAuthentication(AzureEnvironment azureCloud, string tenantId, AzureAuthenticationInfo azureAuthenticationInfo, AzureCredentialsFactory azureCredentialsFactory)
        {
            AzureCredentials credentials;

            switch (azureAuthenticationInfo.Mode)
            {
            case AuthenticationMode.ServicePrincipal:
                credentials = GetServicePrincipleCredentials(azureCloud, tenantId, azureAuthenticationInfo, azureCredentialsFactory);
                break;

            case AuthenticationMode.UserAssignedManagedIdentity:
                credentials = GetUserAssignedManagedIdentityCredentials(azureCloud, tenantId, azureAuthenticationInfo, azureCredentialsFactory);
                break;

            default:
                credentials = GetSystemAssignedManagedIdentityCredentials(azureCloud, tenantId, azureCredentialsFactory);
                break;
            }

            return(credentials);
        }