public static async Task <string> GetAccessToken(
            string accessTokenUri,
            string clientId,
            string clientSecret,
            int timeout = DEFAULT_GETACCESSTOKEN_TIMEOUT,
            bool validateCertificates = DEFAULT_VALIDATE_CERTIFICATES,
            ILogger logger            = null)
        {
            if (string.IsNullOrEmpty(accessTokenUri))
            {
                throw new ArgumentException(nameof(accessTokenUri));
            }

            if (string.IsNullOrEmpty(clientId))
            {
                throw new ArgumentException(nameof(accessTokenUri));
            }

            if (string.IsNullOrEmpty(clientSecret))
            {
                throw new ArgumentException(nameof(accessTokenUri));
            }

            var        request = new HttpRequestMessage(HttpMethod.Post, accessTokenUri);
            HttpClient client  = GetHttpClient(validateCertificates, timeout);

            // If certificate validation is disabled, inject a callback to handle properly
            HttpClientHelper.ConfigureCertificateValidation(validateCertificates, out SecurityProtocolType prevProtocols, out RemoteCertificateValidationCallback prevValidator);

            AuthenticationHeaderValue auth = new AuthenticationHeaderValue("Basic", GetEncodedUserPassword(clientId, clientSecret));

            request.Headers.Authorization = auth;

            request.Content = new FormUrlEncodedContent(new Dictionary <string, string>
            {
                { "grant_type", "client_credentials" }
            });

            try
            {
                using (client)
                {
                    using (HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false))
                    {
                        if (response.StatusCode != HttpStatusCode.OK)
                        {
                            logger?.LogInformation(
                                "GetAccessToken returned status: {0} while obtaining access token from: {1}",
                                response.StatusCode,
                                accessTokenUri);
                            return(null);
                        }

                        var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
                        var token   = payload.Value <string>("access_token");
                        return(token);
                    }
                }
            }
            catch (Exception e)
            {
                logger?.LogError("GetAccessToken exception: {0} ,obtaining access token from: {1}", e, WebUtility.UrlEncode(accessTokenUri));
            }
            finally
            {
                HttpClientHelper.RestoreCertificateValidation(validateCertificates, prevProtocols, prevValidator);
            }

            return(null);
        }