public async Task TestDeviceCodeCancelAsync() { using (var harness = CreateTestHarness()) { const int NumberOfAuthorizationPendingRequestsToInject = 0; var parameters = CreateAuthenticationParametersAndSetupMocks( harness, NumberOfAuthorizationPendingRequestsToInject, out HashSet <string> expectedScopes); var cancellationSource = new CancellationTokenSource(); DeviceCodeResult actualDeviceCodeResult = null; var deviceCodeParameters = new AcquireTokenWithDeviceCodeParameters { DeviceCodeResultCallback = async result => { await Task.Delay(200, CancellationToken.None).ConfigureAwait(false); actualDeviceCodeResult = result; } }; var request = new DeviceCodeRequest(harness.ServiceBundle, parameters, deviceCodeParameters); // We setup the cancel before calling the RunAsync operation since we don't check the cancel // until later and the mock network calls run insanely fast for us to timeout for them. cancellationSource.Cancel(); await AssertException.TaskThrowsAsync <OperationCanceledException>(() => request.RunAsync(cancellationSource.Token)).ConfigureAwait(false); } }
public DeviceCodeRequest( IServiceBundle serviceBundle, AuthenticationRequestParameters authenticationRequestParameters, AcquireTokenWithDeviceCodeParameters deviceCodeParameters) : base(serviceBundle, authenticationRequestParameters, deviceCodeParameters) { _deviceCodeParameters = deviceCodeParameters; }
public Task <AuthenticationResult> ExecuteAsync( AcquireTokenCommonParameters commonParameters, AcquireTokenWithDeviceCodeParameters withDeviceCodeParameters, CancellationToken cancellationToken) { return(ExecuteMatsAsync( commonParameters, async() => await _executor.ExecuteAsync(commonParameters, withDeviceCodeParameters, cancellationToken).ConfigureAwait(false))); }
public void TestDeviceCodeAuthSuccess() { const int NumberOfAuthorizationPendingRequestsToInject = 1; using (var harness = CreateTestHarness()) { var parameters = CreateAuthenticationParametersAndSetupMocks( harness, NumberOfAuthorizationPendingRequestsToInject, out HashSet <string> expectedScopes); var cache = parameters.CacheSessionManager.TokenCacheInternal; // Check that cache is empty Assert.AreEqual(0, cache.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(0, cache.Accessor.GetAllRefreshTokens().Count()); Assert.AreEqual(0, cache.Accessor.GetAllIdTokens().Count()); Assert.AreEqual(0, cache.Accessor.GetAllAccounts().Count()); DeviceCodeResult actualDeviceCodeResult = null; var deviceCodeParameters = new AcquireTokenWithDeviceCodeParameters { DeviceCodeResultCallback = result => { actualDeviceCodeResult = result; return(Task.FromResult(0)); } }; var request = new DeviceCodeRequest(harness.ServiceBundle, parameters, deviceCodeParameters); Task <AuthenticationResult> task = request.RunAsync(CancellationToken.None); task.Wait(); var authenticationResult = task.Result; Assert.IsNotNull(authenticationResult); Assert.IsNotNull(actualDeviceCodeResult); Assert.AreEqual(TestConstants.ClientId, actualDeviceCodeResult.ClientId); Assert.AreEqual(ExpectedDeviceCode, actualDeviceCodeResult.DeviceCode); Assert.AreEqual(ExpectedInterval, actualDeviceCodeResult.Interval); Assert.AreEqual(ExpectedMessage, actualDeviceCodeResult.Message); Assert.AreEqual(ExpectedUserCode, actualDeviceCodeResult.UserCode); Assert.AreEqual(ExpectedVerificationUrl, actualDeviceCodeResult.VerificationUrl); CoreAssert.AreScopesEqual(expectedScopes.AsSingleString(), actualDeviceCodeResult.Scopes.AsSingleString()); // Validate that entries were added to cache Assert.AreEqual(1, cache.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(1, cache.Accessor.GetAllRefreshTokens().Count()); Assert.AreEqual(1, cache.Accessor.GetAllIdTokens().Count()); Assert.AreEqual(1, cache.Accessor.GetAllAccounts().Count()); } }
public async Task <AuthenticationResult> ExecuteAsync( AcquireTokenCommonParameters commonParameters, AcquireTokenWithDeviceCodeParameters deviceCodeParameters, CancellationToken cancellationToken) { var requestContext = CreateRequestContextAndLogVersionInfo(commonParameters.CorrelationId); var requestParams = _publicClientApplication.CreateRequestParameters( commonParameters, requestContext, _publicClientApplication.UserTokenCacheInternal); var handler = new DeviceCodeRequest( ServiceBundle, requestParams, deviceCodeParameters); return(await handler.RunAsync(cancellationToken).ConfigureAwait(false)); }
[WorkItem(1407)] // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1407 public async Task DeviceCodeExceptionsOn200OKAsync() { using (var harness = CreateTestHarness()) { TestCommon.MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); var handler = new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateInvalidClientResponseMessage() }; harness.HttpManager.AddMockHandler(handler); var parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false), account: null); DeviceCodeResult actualDeviceCodeResult = null; var deviceCodeParameters = new AcquireTokenWithDeviceCodeParameters { DeviceCodeResultCallback = result => { actualDeviceCodeResult = result; return(Task.FromResult(0)); } }; var request = new DeviceCodeRequest(harness.ServiceBundle, parameters, deviceCodeParameters); var ex = await AssertException.TaskThrowsAsync <MsalServiceException>( () => request.ExecuteAsync(CancellationToken.None)).ConfigureAwait(false); } }
public void VerifyAuthorizationPendingErrorDoesNotLogError() { // When calling DeviceCodeFlow, we poll for the authorization and if the user hasn't entered the code in yet // then we receive an error for authorization_pending. This is thrown as an exception and logged as // errors. This error is noisy and so it should be suppressed for this one case. // This test verifies that the error for authorization_pending is not logged as an error. var logCallbacks = new List <_LogData>(); using (var harness = CreateTestHarness(logCallback: (level, message, pii) => { if (level == LogLevel.Error) { Assert.Fail( "Received an error message {0} and the stack trace is {1}", message, new StackTrace(true)); } logCallbacks.Add( new _LogData { Level = level, Message = message, IsPii = pii }); })) { const int NumberOfAuthorizationPendingRequestsToInject = 2; var parameters = CreateAuthenticationParametersAndSetupMocks( harness, NumberOfAuthorizationPendingRequestsToInject, out HashSet <string> expectedScopes); var deviceCodeParameters = new AcquireTokenWithDeviceCodeParameters { DeviceCodeResultCallback = result => Task.FromResult(0) }; var request = new DeviceCodeRequest(harness.ServiceBundle, parameters, deviceCodeParameters); Task <AuthenticationResult> task = request.RunAsync(CancellationToken.None); task.Wait(); // Ensure we got logs so the log callback is working. Assert.IsTrue(logCallbacks.Count > 0, "There should be data in logCallbacks"); // Ensure we have authorization_pending data in the logs List <_LogData> authPendingLogs = logCallbacks.Where(x => x.Message.Contains(OAuth2Error.AuthorizationPending)).ToList(); Assert.AreEqual(2, authPendingLogs.Count, "authorization_pending logs should exist"); // Ensure the authorization_pending logs are Info level and not Error Assert.AreEqual( 2, authPendingLogs.Where(x => x.Level == LogLevel.Info).ToList().Count, "authorization_pending logs should be INFO"); // Ensure we don't have Error level logs in this scenario. string errorLogs = string.Join( "--", logCallbacks .Where(x => x.Level == LogLevel.Error) .Select(x => x.Message) .ToArray()); Assert.IsFalse( logCallbacks.Any(x => x.Level == LogLevel.Error), "Error level logs should not exist but got: " + errorLogs); } }