private async Task <AuthenticationResult> AcquireTokenAsync(int userIndex, Metrics localMetrics) { var scopes = new string[] { _options.ApiScopes }; var upn = $"{_options.UsernamePrefix}{userIndex}@{_options.TenantDomain}"; var builder = PublicClientApplicationBuilder .Create(_options.ClientId) .WithAuthority(TestConstants.AadInstance, TestConstants.Organizations); if (_options.EnableMsalLogging) { builder.WithLogging(Logger.Log, LogLevel.Error, false); } var msalPublicClient = builder.Build(); TokenCacheHelper.EnableSerialization(msalPublicClient.UserTokenCache); AuthenticationResult authResult = null; try { try { var identifier = _userAccountIdentifiers[userIndex]; IAccount account = null; if (identifier != null) { var stopwatch = new Stopwatch(); stopwatch.Start(); account = await msalPublicClient.GetAccountAsync(identifier).ConfigureAwait(false); stopwatch.Stop(); localMetrics.TotalMsalLookupTimeInMilliseconds += stopwatch.Elapsed.TotalMilliseconds; } authResult = await msalPublicClient.AcquireTokenSilent(scopes, account).ExecuteAsync(CancellationToken.None).ConfigureAwait(false); return(authResult); } catch (MsalUiRequiredException) { // Delay to prevent spamming the STS with calls. await Task.Delay(_options.RequestDelayInMilliseconds); authResult = await msalPublicClient.AcquireTokenByUsernamePassword( scopes, upn, new NetworkCredential( upn, _options.UserPassword).SecurePassword) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); _userAccountIdentifiers[userIndex] = authResult.Account.HomeAccountId.Identifier; return(authResult); } } catch (Exception ex) { Console.WriteLine($"Exception in AcquireTokenAsync: {ex}"); } return(authResult); }
private async Task SendRequestsAsync(int userStartIndex, int userEndIndex, CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { var localMetrics = new Metrics(); var stopwatch = new Stopwatch(); var exceptionsDuringRun = new StringBuilder(); for (int userIndex = userStartIndex; userIndex <= userEndIndex && !cancellationToken.IsCancellationRequested; userIndex++) { try { HttpResponseMessage response; using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, _options.TestUri)) { AuthenticationResult authResult = await AcquireTokenAsync(userIndex, localMetrics); if (authResult == null) { localMetrics.TotalAcquireTokenFailures++; } else { httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain")); httpRequestMessage.Headers.Add( "Authorization", string.Format( CultureInfo.InvariantCulture, "{0} {1}", "Bearer", authResult?.AccessToken)); stopwatch.Start(); response = await _httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false); stopwatch.Stop(); localMetrics.TotalRequests++; if (authResult?.AuthenticationResultMetadata.TokenSource == TokenSource.Cache) { localMetrics.TotalTokensReturnedFromCache++; } else { if (userIndex % 10 == 0) { TokenCacheHelper.PersistCache(); } } if (!response.IsSuccessStatusCode) { var sb = new StringBuilder(); sb.AppendLine($"Response was not successful. Status code: {response.StatusCode}. {response.ReasonPhrase}"); sb.AppendLine(await response.Content.ReadAsStringAsync()); Console.WriteLine(sb); } } } } catch (Exception ex) { localMetrics.TotalExceptions++; Console.WriteLine($"Exception in TestRunner at {userIndex} of {userEndIndex} - {userStartIndex}: {ex.Message}"); exceptionsDuringRun.AppendLine($"Exception in TestRunner at {userIndex} of {userEndIndex} - {userStartIndex}: {ex.Message}"); exceptionsDuringRun.AppendLine($"{ex}"); } } localMetrics.TotalRequestTimeInMilliseconds += stopwatch.Elapsed.TotalMilliseconds; UpdateGlobalMetrics(localMetrics); DisplayProgress(); TokenCacheHelper.PersistCache(); Logger.PersistExceptions(exceptionsDuringRun); } }