public virtual async Task <XasTokenResponse> GetXTokenAsync(string sandbox, bool forceRefresh)
        {
            if (this.AuthContext == null)
            {
                throw new InvalidOperationException("User Info is not found.");
            }

            XasTokenResponse xToken = null;

            if (!forceRefresh)
            {
                // return cached token if we have one and didn't expire
                string cacheKey = AuthTokenCache.GetCacheKey(this.AuthContext.UserName, this.AuthContext.AccountSource, this.AuthContext.Tenant, string.Empty, sandbox);
                this.XTokenCache.Value.TryGetCachedToken(cacheKey, out xToken);
            }

            if (xToken == null)
            {
                var msaToken = await this.AuthContext.AcquireTokenSilentAsync();

                var xstsToken = await this.FetchXstsToken(msaToken, sandbox);

                xToken = xstsToken;
            }

            return(xToken);
        }
        public virtual async Task <string> GetETokenAsync(string scid, IEnumerable <string> sandboxes, bool forceRefresh)
        {
            if (this.AuthContext == null)
            {
                throw new InvalidOperationException("User Info is not found.");
            }

            if (sandboxes != null && sandboxes.Count() == 0)
            {
                sandboxes = null;
            }

            string eToken = null;

            if (!forceRefresh)
            {
                // return cached token if we have one and didn't expire
                string cacheKey = AuthTokenCache.GetCacheKey(this.AuthContext.UserName, this.AuthContext.AccountSource, this.AuthContext.Tenant, scid, sandboxes);
                this.ETokenCache.Value.TryGetCachedToken(cacheKey, out eToken);
            }

            if (string.IsNullOrEmpty(eToken))
            {
                var aadToken = await this.AuthContext.AcquireTokenSilentAsync();

                var xtdsToken = await this.FetchXdtsToken(aadToken, scid, sandboxes);

                eToken = xtdsToken.Token;
            }

            return(eToken);
        }
        protected async Task <XasTokenResponse> FetchXdtsToken(string aadToken, string scid, IEnumerable <string> sandboxes)
        {
            using (var tokenRequest = new XboxLiveHttpRequest())
            {
                HttpResponseMessage response = (await tokenRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Post, this.AuthContext.XtdsEndpoint);

                    var requestContent = JsonConvert.SerializeObject(new XdtsTokenRequest(scid, sandboxes));
                    requestMsg.Content = new StringContent(requestContent);

                    // Add the aadToken header without validation as the framework
                    // does not like the values returned for aadTokens for MSA accounts.
                    requestMsg.Headers.TryAddWithoutValidation("Authorization", aadToken);

                    return(requestMsg);
                })).Response;

                response.EnsureSuccessStatusCode();
                Log.WriteLog("Fetch xdts Token succeeded.");

                var token = await response.Content.DeserializeJsonAsync <XasTokenResponse>();

                string key = AuthTokenCache.GetCacheKey(this.AuthContext.UserName, this.AuthContext.AccountSource, this.AuthContext.Tenant, scid, sandboxes);
                this.ETokenCache.Value.UpdateToken(key, token);

                return(token);
            }
        }
        protected async Task <XasTokenResponse> FetchXstsToken(string msaToken, string sandbox)
        {
            // Get XASU token
            XasTokenResponse token = null;

            using (var tokenRequest = new XboxLiveHttpRequest())
            {
                HttpResponseMessage response = (await tokenRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Post, ClientSettings.Singleton.XASUEndpoint);

                    XasuTokenRequest xasuTokenRequest = new XasuTokenRequest();
                    xasuTokenRequest.Properties["SiteName"] = "user.auth.xboxlive.com";
                    xasuTokenRequest.Properties["RpsTicket"] = $"d={msaToken}";

                    var requestContent = JsonConvert.SerializeObject(xasuTokenRequest);
                    requestMsg.Content = new StringContent(requestContent);
                    requestMsg.Content.Headers.ContentType.MediaType = "application/json";

                    return(requestMsg);
                })).Response;

                // Get XASU token with MSA token
                response.EnsureSuccessStatusCode();
                Log.WriteLog("Fetch XASU token succeeded.");

                token = await response.Content.DeserializeJsonAsync <XasTokenResponse>();
            }

            // Get XSTS token
            using (var tokenRequest = new XboxLiveHttpRequest())
            {
                HttpResponseMessage response = (await tokenRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Post, ClientSettings.Singleton.XSTSEndpoint);

                    XstsTokenRequest xstsTokenRequest = new XstsTokenRequest(sandbox)
                    {
                        RelyingParty = "http://xboxlive.com"
                    };
                    xstsTokenRequest.Properties["UserTokens"] = new[] { token.Token };

                    var requestContent = JsonConvert.SerializeObject(xstsTokenRequest);
                    requestMsg.Content = new StringContent(requestContent);
                    requestMsg.Content.Headers.ContentType.MediaType = "application/json";

                    return(requestMsg);
                })).Response;

                // Get XASU token with MSA token
                response.EnsureSuccessStatusCode();
                Log.WriteLog("Fetch XSTS token succeeded.");

                token = await response.Content.DeserializeJsonAsync <XasTokenResponse>();
            }

            string key = AuthTokenCache.GetCacheKey(this.AuthContext.UserName, this.AuthContext.AccountSource, this.AuthContext.Tenant, string.Empty, sandbox);

            this.XTokenCache.Value.UpdateToken(key, token);

            return(token);
        }