Example #1
0
        // only works for AAD plugin. MSA plugin does not allow for privacy reasons
        private async Task <MsalTokenResponse> AcquireInteractiveWithAadBrowserAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            Prompt msalPrompt)
        {
            var provider = await _webAccountProviderFactory.GetAccountProviderAsync(
                authenticationRequestParameters.Authority.TenantId).ConfigureAwait(true);

            WebTokenRequest webTokenRequest = await _aadPlugin.CreateWebTokenRequestAsync(
                provider,
                authenticationRequestParameters,
                isForceLoginPrompt : true,
                isInteractive : true,
                isAccountInWam : false)
                                              .ConfigureAwait(false);

            WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequest, _logger);
            AddPromptToRequest(msalPrompt, true, webTokenRequest);

            var wamResult = await _wamProxy.RequestTokenForWindowAsync(
                _parentHandle,
                webTokenRequest).ConfigureAwait(false);

            return(WamAdapters.CreateMsalResponseFromWamResponse(
                       wamResult,
                       _aadPlugin,
                       authenticationRequestParameters.AppConfig.ClientId,
                       _logger,
                       isInteractive: true));
        }
        private async Task <WebAccount> TryFetchWebAccountFromMsaAsync(
            AuthenticationRequestParameters authenticationRequestParameters, WebAccountProvider accountProvider)
        {
            // This response has an v1 MSA Access Token, which MSAL should expose to the user
            var webTokenRequestMsa = await _msaPlugin.CreateWebTokenRequestAsync(
                accountProvider,
                authenticationRequestParameters,
                isForceLoginPrompt : false,
                isInteractive : true,
                isAccountInWam : false)
                                     .ConfigureAwait(false);

            WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequestMsa);

            var webTokenResponseMsa = await _wamProxy.RequestTokenForWindowAsync(_parentHandle, webTokenRequestMsa)
                                      .ConfigureAwait(true);

            if (!webTokenResponseMsa.ResponseStatus.IsSuccessStatus())
            {
                var errorResp = WamAdapters.CreateMsalResponseFromWamResponse(webTokenResponseMsa, _msaPlugin, _logger, true);
                _logger.Warning(
                    "WAM MSA-PT: could not get a transfer token, ussually this is because the " +
                    "1st party app is configured for MSA-PT but not configured to login MSA users (signinaudience =2). " +
                    "Error was: " + errorResp.Error + " " + errorResp.ErrorDescription);

                return(null);
            }

            // Cannot use this WebAccount with the AAD provider
            WebAccount msaPtWebAccount = webTokenResponseMsa.ResponseData[0].WebAccount;

            return(msaPtWebAccount);
        }
        public async Task ATI_WithoutPicker_Async()
        {
            string homeAccId = $"{TestConstants.Uid}.{TestConstants.Utid}";

            // Arrange
            using (var harness = CreateTestHarness())
            {
                var requestParams = harness.CreateAuthenticationRequestParameters(TestConstants.AuthorityHomeTenant); // AAD
                requestParams.Account = new Account(
                    $"{TestConstants.Uid}.{TestConstants.Utid}",
                    TestConstants.DisplayableId,
                    null,
                    new Dictionary <string, string>()
                {
                    { TestConstants.ClientId, "wam_id_1" }
                });                                                                              // account has wam_id!

                var wamAccountProvider = new WebAccountProvider("id", "*****@*****.**", null);
                var webAccount         = new WebAccount(wamAccountProvider, "*****@*****.**", WebAccountState.Connected);
                var webTokenRequest    = new WebTokenRequest(wamAccountProvider);

                // will use the AAD provider because the authority is tenanted (i.e. AAD only)
                _webAccountProviderFactory
                .GetAccountProviderAsync(TestConstants.AuthorityHomeTenant)
                .ReturnsForAnyArgs(Task.FromResult(wamAccountProvider));

                // account matching based on wam account ID (logic for matching based on home_account_id is checked in ATS tests)
                _wamProxy.FindAccountAsync(Arg.Any <WebAccountProvider>(), "wam_id_1")
                .Returns(Task.FromResult(webAccount));

                // WAM can give MSAL the home account ID of a Wam account, which MSAL matches to a WAM account
                _aadPlugin.CreateWebTokenRequestAsync(
                    wamAccountProvider,
                    requestParams,
                    isForceLoginPrompt: false,
                    isAccountInWam: true,
                    isInteractive: true)
                .Returns(Task.FromResult(webTokenRequest));

                var webTokenResponseWrapper = Substitute.For <IWebTokenRequestResultWrapper>();
                webTokenResponseWrapper.ResponseStatus.Returns(WebTokenRequestStatus.Success);
                var webTokenResponse = new WebTokenResponse();
                webTokenResponseWrapper.ResponseData.Returns(new List <WebTokenResponse>()
                {
                    webTokenResponse
                });

                _wamProxy.RequestTokenForWindowAsync(Arg.Any <IntPtr>(), webTokenRequest, webAccount).
                Returns(Task.FromResult(webTokenResponseWrapper));
                _aadPlugin.ParseSuccesfullWamResponse(webTokenResponse).Returns(_msalTokenResponse);

                // Act
                var result = await _wamBroker.AcquireTokenInteractiveAsync(
                    requestParams,
                    new AcquireTokenInteractiveParameters()).ConfigureAwait(false);

                // Assert
                Assert.AreSame(_msalTokenResponse, result);
            }
        }
Example #4
0
        private async Task <WebAccount> FetchWebAccountFromMsaAsync(
            AuthenticationRequestParameters authenticationRequestParameters, WebAccountProvider accountProvider)
        {
            // This response has an v1 MSA Access Token, which MSAL should expose to the user
            var webTokenRequestMsa = await _msaPlugin.CreateWebTokenRequestAsync(
                accountProvider,
                authenticationRequestParameters,
                isForceLoginPrompt : false,
                isInteractive : true,
                isAccountInWam : false)
                                     .ConfigureAwait(false);

            WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequestMsa);

            var webTokenResponseMsa = await _wamProxy.RequestTokenForWindowAsync(_parentHandle, webTokenRequestMsa)
                                      .ConfigureAwait(true);

            if (!webTokenResponseMsa.ResponseStatus.IsSuccessStatus())
            {
                var errorResp = WamAdapters.CreateMsalResponseFromWamResponse(webTokenResponseMsa, _msaPlugin, _logger, true);
                throw new MsalServiceException(
                          errorResp.Error,
                          "Error fetching the MSA-PT initial token - " + errorResp.ErrorDescription);
            }

            // Cannot use this WebAccount with the AAD provider
            WebAccount msaPtWebAccount = webTokenResponseMsa.ResponseData[0].WebAccount;

            return(msaPtWebAccount);
        }
Example #5
0
        private async Task <IWebTokenRequestResultWrapper> AcquireInteractiveWithoutPickerAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            Prompt prompt,
            IWamPlugin wamPlugin,
            WebAccountProvider provider,
            WebAccount wamAccount)
        {
            bool isForceLoginPrompt = IsForceLoginPrompt(prompt);

            WebTokenRequest webTokenRequest = await wamPlugin.CreateWebTokenRequestAsync(
                provider,
                authenticationRequestParameters,
                isForceLoginPrompt : isForceLoginPrompt,
                isInteractive : true,
                isAccountInWam : true)
                                              .ConfigureAwait(false);

            if (isForceLoginPrompt &&
                ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 6))
            {
                // this feature works correctly since windows RS4, aka 1803 with the AAD plugin only!
                webTokenRequest.Properties["prompt"] = prompt.PromptValue;
            }

            AddCommonParamsToRequest(authenticationRequestParameters, webTokenRequest);

            try
            {
#if WINDOWS_APP
                // UWP requires being on the UI thread
                await _synchronizationContext;
#endif
                IWebTokenRequestResultWrapper wamResult;
                if (wamAccount != null)
                {
                    wamResult = await _wamProxy.RequestTokenForWindowAsync(
                        _parentHandle,
                        webTokenRequest,
                        wamAccount).ConfigureAwait(false);
                }
                else
                {
                    // default user
                    wamResult = await _wamProxy.RequestTokenForWindowAsync(
                        _parentHandle,
                        webTokenRequest).ConfigureAwait(false);
                }
                return(wamResult);
            }
            catch (Exception ex)
            {
                _logger.ErrorPii(ex);
                throw new MsalServiceException(
                          MsalError.WamInteractiveError,
                          "AcquireTokenInteractive without picker failed. See inner exception for details. ", ex);
            }
        }
        private async Task <IWebTokenRequestResultWrapper> AcquireInteractiveWithoutPickerAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            Prompt msalPrompt,
            IWamPlugin wamPlugin,
            WebAccountProvider provider,
            WebAccount wamAccount)
        {
            bool isForceLoginPrompt = IsForceLoginPrompt(msalPrompt);

            WebTokenRequest webTokenRequest = await wamPlugin.CreateWebTokenRequestAsync(
                provider,
                authenticationRequestParameters,
                isForceLoginPrompt : isForceLoginPrompt,
                isInteractive : true,
                isAccountInWam : true)
                                              .ConfigureAwait(false);

            AddPromptToRequest(msalPrompt, isForceLoginPrompt, webTokenRequest);

            WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequest);

            try
            {
                IWebTokenRequestResultWrapper wamResult;
                if (wamAccount != null)
                {
                    wamResult = await _wamProxy.RequestTokenForWindowAsync(
                        _parentHandle,
                        webTokenRequest,
                        wamAccount).ConfigureAwait(false);
                }
                else
                {
                    // default user
                    wamResult = await _wamProxy.RequestTokenForWindowAsync(
                        _parentHandle,
                        webTokenRequest).ConfigureAwait(false);
                }
                return(wamResult);
            }
            catch (Exception ex)
            {
                _logger.ErrorPii(ex);
                throw new MsalServiceException(
                          MsalError.WamInteractiveError,
                          "AcquireTokenInteractive without picker failed. See inner exception for details. ", ex);
            }
        }
        public async Task FetchTransferToken_Silent_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                var msaProvider = new WebAccountProvider("id", "*****@*****.**", null);

                Client.Internal.Requests.AuthenticationRequestParameters requestParams =
                    harness.CreateAuthenticationRequestParameters(
                        TestConstants.AuthorityHomeTenant,
                        validateAuthority: true);
                requestParams.AppConfig.WindowsBrokerOptions = new WindowsBrokerOptions()
                {
                    MsaPassthrough = true
                };
                var msaRequest = new WebTokenRequest(msaProvider);

                _msaPlugin.CreateWebTokenRequestAsync(msaProvider, requestParams, false, false, true, MsaPassthroughHandler.TransferTokenScopes)
                .Returns(Task.FromResult(msaRequest));

                var webTokenResponseWrapper = Substitute.For <IWebTokenRequestResultWrapper>();
                webTokenResponseWrapper.ResponseStatus.Returns(WebTokenRequestStatus.Success);
                WebAccount accountFromMsaProvider = new WebAccount(msaProvider, "*****@*****.**", WebAccountState.Connected);
                var        webTokenResponse       = new WebTokenResponse("transfer_token", accountFromMsaProvider);
                webTokenResponseWrapper.ResponseData.Returns(new List <WebTokenResponse>()
                {
                    webTokenResponse
                });
                _wamProxy.RequestTokenForWindowAsync(IntPtr.Zero, msaRequest, accountFromMsaProvider).Returns(webTokenResponseWrapper);
                _msaPlugin.ParseSuccessfullWamResponse(Arg.Any <WebTokenResponse>(), out Arg.Any <Dictionary <string, string> >())
                .Returns(x =>
                {
                    x[1] = new Dictionary <string, string>();
                    (x[1] as Dictionary <string, string>).Add("code", "actual_transfer_token");
                    return(new MsalTokenResponse());
                });

                // Act
                var transferToken = await _msaPassthroughHandler.TryFetchTransferTokenSilentAsync(
                    requestParams,
                    accountFromMsaProvider)
                                    .ConfigureAwait(false);

                // Assert
                Assert.AreEqual("actual_transfer_token", transferToken);
            }
        }
Example #8
0
        public async Task <string> TryFetchTransferTokenInteractiveAsync(AuthenticationRequestParameters authenticationRequestParameters, WebAccountProvider accountProvider)
        {
            // First party apps can have MSA-PT enabled and can configured to allow MSA users
            _logger.Verbose("WAM MSA-PT - fetching transfer token for interactive flow");

            var webTokenRequestMsa = await _msaPlugin.CreateWebTokenRequestAsync(
                accountProvider,
                authenticationRequestParameters,
                isForceLoginPrompt : false,
                isInteractive : true,
                isAccountInWam : false,
                TransferTokenScopes)
                                     .ConfigureAwait(false);

            WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequestMsa, _logger);

            var transferResponse = await _wamProxy.RequestTokenForWindowAsync(_parentHandle, webTokenRequestMsa)
                                   .ConfigureAwait(true);

            return(ExtractTransferToken(
                       authenticationRequestParameters.AppConfig.ClientId,
                       transferResponse,
                       isInteractive: true));
        }