/// <summary> /// Returns an access token depending on the type requested for testing. /// </summary> /// <returns></returns> private Task <AppAuthenticationResult> AcquireTokenAsync() { AppAuthenticationResult authResult; switch (_mockAuthenticationContextTestType) { case MockAuthenticationContextTestType.AcquireTokenSilentAsyncFail: case MockAuthenticationContextTestType.AcquireTokenAsyncClientCertificateFail: case MockAuthenticationContextTestType.AcquireTokenAsyncClientCredentialFail: case MockAuthenticationContextTestType.AcquireTokenAsyncUserCredentialFail: return(Task.FromResult <AppAuthenticationResult>(null)); case MockAuthenticationContextTestType.AcquireInvalidTokenAsyncFail: authResult = AppAuthenticationResult.Create(TokenHelper.GetInvalidAppToken()); return(Task.FromResult(authResult)); case MockAuthenticationContextTestType.AcquireTokenAsyncException: throw new Exception(Constants.AdalException); case MockAuthenticationContextTestType.AcquireTokenSilentAsyncSuccess: case MockAuthenticationContextTestType.AcquireTokenAsyncUserCredentialSuccess: authResult = AppAuthenticationResult.Create(TokenHelper.GetUserToken()); return(Task.FromResult(authResult)); case MockAuthenticationContextTestType.AcquireTokenAsyncClientCertificateSuccess: case MockAuthenticationContextTestType.AcquireTokenAsyncClientCredentialSuccess: authResult = AppAuthenticationResult.Create(TokenHelper.GetAppToken()); return(Task.FromResult(authResult)); } return(null); }
public async Task GetAppAuthResultCacheTest() { // Create two instances of AzureServiceTokenProvider based on AzureCliAccessTokenProvider. MockProcessManager mockProcessManager = new MockProcessManager(MockProcessManager.MockProcessManagerRequestType.Success); AzureCliAccessTokenProvider azureCliAccessTokenProvider = new AzureCliAccessTokenProvider(mockProcessManager); AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(azureCliAccessTokenProvider); AzureServiceTokenProvider azureServiceTokenProvider1 = new AzureServiceTokenProvider(azureCliAccessTokenProvider); List <Task> tasks = new List <Task>(); // ManualResetEvent will enable testing of SemaphoreSlim used in AzureServiceTokenProvider. ManualResetEvent manualResetEvent = new ManualResetEvent(false); // Use AzureServiceTokenProviders to get tokens in parallel. for (int i = 0; i < 5; i++) { Task task = Task.Run(async delegate { // This will prevent the next line from running, until manualResetEvent.Set() is called. // This will ensure all GetAccessTokenAsync calls are made at once. manualResetEvent.WaitOne(); await azureServiceTokenProvider.GetAccessTokenAsync(Constants.KeyVaultResourceId); }); tasks.Add(task); Task task1 = Task.Run(async delegate { manualResetEvent.WaitOne(); // This is using the other instance of AzureServiceTokenProvider. await azureServiceTokenProvider1.GetAccessTokenAsync(Constants.KeyVaultResourceId); }); tasks.Add(task1); } // This will cause GetAccessTokenAsync calls to be made concurrently. manualResetEvent.Set(); await Task.WhenAll(tasks); // Even though multiple calls are made to get token concurrently, using two different instances, the process manager should only be called once. // This test tells us that the cache is working as intended. Assert.Equal(1, mockProcessManager.HitCount); // Get the token again. This will test if the cache call before semaphore use is working as intended. for (int i = 0; i < 5; i++) { tasks.Add(azureServiceTokenProvider.GetAccessTokenAsync(Constants.KeyVaultResourceId)); } await Task.WhenAll(tasks); // The hit count should still be 1, since the token should be fetched from cache. Assert.Equal(1, mockProcessManager.HitCount); // Update the cache entry, to simulate token expiration. This updated token will expire in just less than 5 minutes. // In a real scenario, the token will expire after some time. // AppAuthResultCache should not return this, since it is about to expire. var tokenResponse = TokenResponse.Parse(TokenHelper.GetUserTokenResponse(5 * 60 - 2)); var authResult = AppAuthenticationResult.Create(tokenResponse, TokenResponse.DateFormat.DateTimeString); AppAuthResultCache.AddOrUpdate("ConnectionString:;Authority:;Resource:https://vault.azure.net/", new Tuple <AppAuthenticationResult, Principal>(authResult, null)); // Get the token again. for (int i = 0; i < 5; i++) { tasks.Add(azureServiceTokenProvider.GetAccessTokenAsync(Constants.KeyVaultResourceId)); } await Task.WhenAll(tasks); // Hit count should be 2 now, since new token should have been aquired. Assert.Equal(2, mockProcessManager.HitCount); }