예제 #1
0
        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);
            }
        }
예제 #2
0
 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)));
 }
예제 #4
0
        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());
            }
        }
예제 #5
0
        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));
        }
예제 #6
0
        [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);
            }
        }
예제 #7
0
        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);
            }
        }