// Gets an access token. First tries to get the access token from the token cache.
        // Using password (secret) to authenticate. Production apps should use a certificate.
        public async Task <string> GetUserAccessTokenAsync(string userId)
        {
            var account = await _app.GetAccountAsync(userId);

            if (account == null)
            {
                throw new ServiceException(new Error
                {
                    Code    = "TokenNotFound",
                    Message = "User not found in token cache. Maybe the server was restarted."
                });
            }

            try
            {
                var result = await _app.AcquireTokenSilentAsync(_scopes, account);

                return(result.AccessToken);
            }

            // Unable to retrieve the access token silently.
            catch (Exception)
            {
                throw new ServiceException(new Error
                {
                    Code    = GraphErrorCode.AuthenticationFailure.ToString(),
                    Message = "Caller needs to authenticate. Unable to retrieve the access token silently."
                });
            }
        }
        // GET: Admin
        public async Task <ActionResult> Index()
        {
            string[] scopes = adminScopes.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            SessionTokenCacheProvider      sessionTokenCacheProvider = new SessionTokenCacheProvider(this.HttpContext);
            IConfidentialClientApplication cca = AuthorizationCodeProvider.CreateClientApplication(clientId, redirectUri, new ClientCredential(appKey), sessionTokenCacheProvider);

            try
            {
                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, (await cca.GetAccountsAsync()).FirstOrDefault());
            }
            catch (Exception)
            {
                try
                {// when failing, manufacture the URL and assign it
                    string authReqUrl = await OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca as ConfidentialClientApplication, this.HttpContext, Url);

                    ViewBag.AuthorizationRequest = authReqUrl;
                }
                catch (Exception ee)
                {
                }
            }

            return(View("Admin"));
        }
        /// <summary>
        /// Gets an access token for a downstream API on behalf of the user which account ID is passed as an argument
        /// </summary>
        /// <param name="accountIdentifier">User account identifier for which to acquire a token.
        /// See <see cref="Microsoft.Identity.Client.AccountId.Identifier"/></param>
        /// <param name="scopes">Scopes for the downstream API to call</param>
        private async Task <string> GetAccessTokenOnBehalfOfUser(IConfidentialClientApplication application, string accountIdentifier, IEnumerable <string> scopes, string loginHint, string tenant)
        {
            if (accountIdentifier == null)
            {
                throw new ArgumentNullException(nameof(accountIdentifier));
            }

            if (scopes == null)
            {
                throw new ArgumentNullException(nameof(scopes));
            }

            // Get the account
            IAccount account = await application.GetAccountAsync(accountIdentifier);

            // Special case for guest users as the Guest iod / tenant id are not surfaced.
            if (account == null)
            {
                var accounts = await application.GetAccountsAsync();

                account = accounts.FirstOrDefault(a => a.Username == loginHint);
            }

            AuthenticationResult result;

            if (string.IsNullOrWhiteSpace(tenant))
            {
                result = await application.AcquireTokenSilentAsync(scopes.Except(scopesRequestedByMsalNet), account);
            }
            else
            {
                string authority = application.Authority.Replace(new Uri(application.Authority).PathAndQuery, $"/{tenant}/");
                result = await application.AcquireTokenSilentAsync(scopes.Except(scopesRequestedByMsalNet), account, authority, false);
            }
            return(result.AccessToken);
        }