private async Task <MsalTokenResponse> GetTokenResponseAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (_requestParams.AppConfig.IsBrokerEnabled)
            {
                _logger.Info("Broker is configured. Starting broker flow without knowing the broker installation app link. ");

                MsalTokenResponse brokerTokenResponse = await FetchTokensFromBrokerAsync(
                    null, // we don't have an installation URI yet
                    cancellationToken)
                                                        .ConfigureAwait(false);

                // if we don't get back a result, then continue with the WebUi
                if (brokerTokenResponse != null)
                {
                    _logger.Info("Broker attempt completed successfully. ");
                    Metrics.IncrementTotalAccessTokensFromBroker();
                    return(brokerTokenResponse);
                }

                _logger.Info("Broker attempt did not complete, most likely because the broker is not installed. Attempting to use a browser / web UI. ");
                cancellationToken.ThrowIfCancellationRequested();
            }

            IAuthCodeRequestComponent authorizationFetcher =
                _authCodeRequestComponentOverride ??
                new AuthCodeRequestComponent(
                    _requestParams,
                    _interactiveParameters);

            var result = await authorizationFetcher.FetchAuthCodeAndPkceVerifierAsync(cancellationToken)
                         .ConfigureAwait(false);

            _logger.Info("An authorization code was retrieved from the /authorize endpoint. ");
            AuthorizationResult authResult = result.Item1;
            string authCode         = authResult.Code;
            string pkceCodeVerifier = result.Item2;

            if (BrokerInteractiveRequestComponent.IsBrokerRequiredAuthCode(authCode, out string brokerInstallUri))
            {
                return(await RunBrokerWithInstallUriAsync(brokerInstallUri, cancellationToken).ConfigureAwait(false));
            }

            _logger.Info("Exchanging the auth code for tokens. ");
            var authCodeExchangeComponent =
                _authCodeExchangeComponentOverride ??
                new AuthCodeExchangeComponent(
                    _requestParams,
                    _interactiveParameters,
                    authCode,
                    pkceCodeVerifier,
                    authResult.ClientInfo);

            MsalTokenResponse idpTokenResponse = await authCodeExchangeComponent.FetchTokensAsync(cancellationToken)
                                                 .ConfigureAwait(false);

            Metrics.IncrementTotalAccessTokensFromIdP();
            return(idpTokenResponse);
        }
예제 #2
0
        public async Task NoBroker_WebUiOnly_Async()
        {
            // Arrange - common stuff
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                MockInstanceDiscovery(harness.HttpManager);

                ITokenCacheInternal cache = new TokenCache(harness.ServiceBundle, false);

                var requestParams = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    cache);
                var interactiveParameters = new AcquireTokenInteractiveParameters();

                // Arrange - important for test
                requestParams.AppConfig.IsBrokerEnabled = false;
                var authCodeResult = new Tuple <AuthorizationResult, string>(new AuthorizationResult()
                {
                    Code = "some_auth_code"
                }, "pkce_verifier");
                _authCodeRequestComponentOverride.FetchAuthCodeAndPkceVerifierAsync(CancellationToken.None)
                .Returns(Task.FromResult(authCodeResult));

                _authCodeExchangeComponentOverride.FetchTokensAsync(CancellationToken.None)
                .Returns(Task.FromResult(_msalTokenResponse));

                InteractiveRequest interactiveRequest = new InteractiveRequest(
                    requestParams,
                    interactiveParameters,
                    _authCodeRequestComponentOverride,
                    _authCodeExchangeComponentOverride,
                    _brokerExchangeComponentOverride);

                // Act
                AuthenticationResult result = await interactiveRequest.RunAsync().ConfigureAwait(false);

                // Assert - common stuff
                Assert.IsNotNull(result);
                Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
                Assert.IsTrue(!string.IsNullOrEmpty(result.AccessToken));
                Assert.AreEqual(1, cache.Accessor.GetAllAccessTokens().Count());

                // Assert - orchestration
#pragma warning disable VSTHRD101 // Avoid unsupported async delegates
                Received.InOrder(async() =>
                {
                    await _authCodeRequestComponentOverride
                    .FetchAuthCodeAndPkceVerifierAsync(default)
        private async Task <MsalTokenResponse> GetTokenResponseAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (_requestParams.AppConfig.IsBrokerEnabled)
            {
                _logger.Info("Broker is configured. Starting broker flow without knowing the broker installation app link. ");

                MsalTokenResponse brokerTokenResponse = await FetchTokensFromBrokerAsync(
                    null, // we don't have an installation URI yet
                    cancellationToken)
                                                        .ConfigureAwait(false);

                // if we don't get back a result, then continue with the WebUi
                if (brokerTokenResponse != null)
                {
                    _logger.Info("Broker attempt completed successfully. ");
                    Metrics.IncrementTotalAccessTokensFromBroker();
                    return(brokerTokenResponse);
                }

                if (string.Equals(_requestParams.AuthenticationScheme.AccessTokenType, Constants.PoPTokenType))
                {
                    _logger.Error("A broker application is required for Proof-of-Possesion, but one could not be found or communicated with. See https://aka.ms/msal-net-pop");
                    throw new MsalClientException(MsalError.BrokerApplicationRequired, MsalErrorMessage.CannotInvokeBrokerForPop);
                }

                _logger.Info("Broker attempt did not complete, most likely because the broker is not installed. Attempting to use a browser / web UI. ");

                cancellationToken.ThrowIfCancellationRequested();
            }

            if (_requestParams.AppConfig.MultiCloudSupportEnabled)
            {
                _logger.Info("Instance Aware was configured.");
                _requestParams.AppConfig.ExtraQueryParameters[InstanceAwareParam] = "true";
            }

            IAuthCodeRequestComponent authorizationFetcher =
                _authCodeRequestComponentOverride ??
                new AuthCodeRequestComponent(
                    _requestParams,
                    _interactiveParameters);

            var result = await authorizationFetcher.FetchAuthCodeAndPkceVerifierAsync(cancellationToken)
                         .ConfigureAwait(false);

            _logger.Info("An authorization code was retrieved from the /authorize endpoint. ");
            AuthorizationResult authResult = result.Item1;
            string authCode         = authResult.Code;
            string pkceCodeVerifier = result.Item2;

            if (BrokerInteractiveRequestComponent.IsBrokerRequiredAuthCode(authCode, out string brokerInstallUri))
            {
                return(await RunBrokerWithInstallUriAsync(brokerInstallUri, cancellationToken).ConfigureAwait(false));
            }

            if (_requestParams.AppConfig.MultiCloudSupportEnabled && !string.IsNullOrEmpty(authResult.CloudInstanceHost))
            {
                _logger.Info("Updating the authority to the cloud specific authority.");
                _requestParams.AuthorityManager = new AuthorityManager(
                    _requestParams.RequestContext,
                    Authority.CreateAuthorityWithEnvironment(_requestParams.Authority.AuthorityInfo, authResult.CloudInstanceHost));

                await ResolveAuthorityAsync().ConfigureAwait(false);
            }

            _logger.Info("Exchanging the auth code for tokens. ");
            var authCodeExchangeComponent =
                _authCodeExchangeComponentOverride ??
                new AuthCodeExchangeComponent(
                    _requestParams,
                    _interactiveParameters,
                    authCode,
                    pkceCodeVerifier,
                    authResult.ClientInfo);

            MsalTokenResponse idpTokenResponse = await authCodeExchangeComponent.FetchTokensAsync(cancellationToken)
                                                 .ConfigureAwait(false);

            Metrics.IncrementTotalAccessTokensFromIdP();
            return(idpTokenResponse);
        }