// Get the access token via straight http post request doing client credential flow
        private async Task <String> GetAppOnlyAccessTokenWithHttpRequest(string resource, string tenantId)
        {
            /**
             * use the tenant specific endpoint for requesting the app-only access token
             */
            string tokenIssueEndpoint = appConfig.TokenIssueingUri.Replace("common", tenantId);

            /**
             * sign the assertion with the private key
             */
            string           certfile = Server.MapPath(appConfig.ClientCertificatePfx);
            X509Certificate2 cert     = new X509Certificate2(
                certfile,
                appConfig.ClientCertificatePfxPassword,
                X509KeyStorageFlags.MachineKeySet);

            /**
             * Example building assertion using Json Tokenhandler.
             * Sort of cheating, but just if someone wonders ... there are always more ways to do something :-)
             */
            Dictionary <string, string> claims = new Dictionary <string, string>()
            {
                { "sub", appConfig.ClientId },
                { "jti", Guid.NewGuid().ToString() },
            };

            JwtSecurityTokenHandler tokenHandler       = new JwtSecurityTokenHandler();
            X509SigningCredentials  signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);

            JwtSecurityToken selfSignedToken = new JwtSecurityToken(
                appConfig.ClientId,
                tokenIssueEndpoint,
                claims.Select(c => new Claim(c.Key, c.Value)),
                DateTime.UtcNow,
                DateTime.UtcNow.Add(TimeSpan.FromMinutes(15)),
                signingCredentials);

            string signedAssertion = tokenHandler.WriteToken(selfSignedToken);

            //---- End example with Json Tokenhandler... now to the fun part doing it all ourselves ...

            /**
             * Example building assertion from scratch with Crypto APIs
             */
            JObject clientAssertion = new JObject();

            clientAssertion.Add("aud", tokenIssueEndpoint);
            clientAssertion.Add("iss", appConfig.ClientId);
            clientAssertion.Add("sub", appConfig.ClientId);
            clientAssertion.Add("jti", Guid.NewGuid().ToString());
            clientAssertion.Add("nbf", WebConvert.EpocTime(DateTime.UtcNow + TimeSpan.FromMinutes(-5)));
            clientAssertion.Add("exp", WebConvert.EpocTime(DateTime.UtcNow + TimeSpan.FromMinutes(15)));

            string assertionPayload = clientAssertion.ToString(Newtonsoft.Json.Formatting.None);

            X509AsymmetricSecurityKey x509Key = new X509AsymmetricSecurityKey(cert);
            RSACryptoServiceProvider  rsa     = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSACryptoServiceProvider;
            RSACryptoServiceProvider  newRsa  = GetCryptoProviderForSha256(rsa);
            SHA256Cng sha = new SHA256Cng();

            JObject header     = new JObject(new JProperty("alg", "RS256"));
            string  thumbprint = WebConvert.Base64UrlEncoded(WebConvert.HexStringToBytes(cert.Thumbprint));

            header.Add(new JProperty("x5t", thumbprint));

            string encodedHeader  = WebConvert.Base64UrlEncoded(header.ToString());
            string encodedPayload = WebConvert.Base64UrlEncoded(assertionPayload);

            string signingInput = String.Concat(encodedHeader, ".", encodedPayload);

            byte[] signature = newRsa.SignData(Encoding.UTF8.GetBytes(signingInput), sha);

            signedAssertion = string.Format("{0}.{1}.{2}",
                                            encodedHeader,
                                            encodedPayload,
                                            WebConvert.Base64UrlEncoded(signature));

            /**
             * build the request payload
             */
            FormUrlEncodedContent tokenRequestForm;

            tokenRequestForm = new FormUrlEncodedContent(
                new[] {
                new KeyValuePair <string, string>("resource", appConfig.ExchangeResourceUri),
                new KeyValuePair <string, string>("client_id", appConfig.ClientId),
                new KeyValuePair <string, string>("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"),
                new KeyValuePair <string, string>("client_assertion", signedAssertion),
                new KeyValuePair <string, string>("grant_type", "client_credentials"),
            }
                );

            /*
             * Do the web request
             */
            HttpClient client = new HttpClient();

            Task <string> requestString  = tokenRequestForm.ReadAsStringAsync();
            StringContent requestContent = new StringContent(requestString.Result);

            requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
            requestContent.Headers.Add("client-request-id", System.Guid.NewGuid().ToString());
            requestContent.Headers.Add("return-client-request-id", "true");
            requestContent.Headers.Add("UserAgent", "MatthiasLeibmannsAppOnlyAppSampleBeta/0.1");

            HttpResponseMessage response       = client.PostAsync(tokenIssueEndpoint, requestContent).Result;
            JObject             jsonResponse   = JObject.Parse(response.Content.ReadAsStringAsync().Result);
            JsonSerializer      jsonSerializer = new JsonSerializer();

            if (response.IsSuccessStatusCode == true)
            {
                AADClientCredentialSuccessResponse s = (AADClientCredentialSuccessResponse)jsonSerializer.Deserialize(new JTokenReader(jsonResponse), typeof(AADClientCredentialSuccessResponse));
                return(s.access_token);
            }

            AADClientCredentialErrorResponse e = (AADClientCredentialErrorResponse)jsonSerializer.Deserialize(new JTokenReader(jsonResponse), typeof(AADClientCredentialErrorResponse));

            throw new Exception(e.error_description);
        }