예제 #1
0
        private MsalTokenResponse CreateMsalTokenResponse(
            IWebTokenRequestResultWrapper wamResponse,
            IWamPlugin wamPlugin,
            bool isInteractive)
        {
            string internalErrorCode = null;
            string errorMessage;
            string errorCode;

            switch (wamResponse.ResponseStatus)
            {
            case WebTokenRequestStatus.Success:
                _logger.Info("WAM response status success");
                return(wamPlugin.ParseSuccesfullWamResponse(wamResponse.ResponseData[0]));

            // Account Switch occurs when a login hint is passed to WAM but the user chooses a different account for login.
            // MSAL treats this as a success scenario
            case WebTokenRequestStatus.AccountSwitch:
                _logger.Info("WAM response status account switch. Treating as success");
                return(wamPlugin.ParseSuccesfullWamResponse(wamResponse.ResponseData[0]));

            case WebTokenRequestStatus.UserInteractionRequired:
                errorCode =
                    wamPlugin.MapTokenRequestError(wamResponse.ResponseStatus, wamResponse.ResponseError?.ErrorCode ?? 0, isInteractive);
                internalErrorCode = (wamResponse.ResponseError?.ErrorCode ?? 0).ToString(CultureInfo.InvariantCulture);
                errorMessage      = WamErrorPrefix +
                                    $"Wam plugin {wamPlugin.GetType()}" +
                                    $" error code: {internalErrorCode}" +
                                    $" error: " + wamResponse.ResponseError?.ErrorMessage;
                break;

            case WebTokenRequestStatus.UserCancel:
                errorCode    = MsalError.AuthenticationCanceledError;
                errorMessage = MsalErrorMessage.AuthenticationCanceled;
                break;

            case WebTokenRequestStatus.ProviderError:
                errorCode =
                    wamPlugin.MapTokenRequestError(wamResponse.ResponseStatus, wamResponse.ResponseError?.ErrorCode ?? 0, isInteractive);
                errorMessage      = WamErrorPrefix + wamPlugin.GetType() + wamResponse.ResponseError?.ErrorMessage;
                internalErrorCode = (wamResponse.ResponseError?.ErrorCode ?? 0).ToString(CultureInfo.InvariantCulture);
                break;

            default:
                errorCode         = MsalError.UnknownBrokerError;
                internalErrorCode = wamResponse.ResponseError.ErrorCode.ToString(CultureInfo.InvariantCulture);
                errorMessage      = $"Unknown WebTokenRequestStatus {wamResponse.ResponseStatus} (internal error code {internalErrorCode})";
                break;
            }

            return(new MsalTokenResponse()
            {
                Error = errorCode,
                ErrorCodes = internalErrorCode != null ? new[] { internalErrorCode } : null,
                ErrorDescription = errorMessage
            });
        }
        public async Task FetchTransferToken_FailSilently_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, true, false, MsaPassthroughHandler.TransferTokenScopes)
                .Returns(Task.FromResult(msaRequest));
                _msaPlugin.MapTokenRequestError(WebTokenRequestStatus.ProviderError, 0, true)
                .Returns(Tuple.Create("some_provider_error", "", false));

                var webTokenResponseWrapper = Substitute.For <IWebTokenRequestResultWrapper>();

                webTokenResponseWrapper.ResponseStatus.Returns(WebTokenRequestStatus.ProviderError);
                _wamProxy.RequestTokenForWindowAsync(IntPtr.Zero, msaRequest).Returns(webTokenResponseWrapper);

                // Act
                var transferToken = await _msaPassthroughHandler.TryFetchTransferTokenInteractiveAsync(requestParams, msaProvider)
                                    .ConfigureAwait(false);

                // Assert
                Assert.IsNull(transferToken);
            }
        }
        public async Task WAMBroker_CreateMsalTokenResponse_UserInteractionRequired_Async()
        {
            // Arrange
            using (var harness = CreateTestHarness())
            {
                var(requestParams, webTokenResponseWrapper) = SetupSilentCall(harness);
                webTokenResponseWrapper.ResponseStatus.Returns(WebTokenRequestStatus.UserInteractionRequired);
                webTokenResponseWrapper.ResponseError.Returns(new WebProviderError(42, "more_detailed_error_message"));
                _aadPlugin.MapTokenRequestError(WebTokenRequestStatus.UserInteractionRequired, 42, false)
                .Returns("ui_is_really_needed");

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

                // Assert
                Assert.AreEqual("ui_is_really_needed", result.Error);
                Assert.AreEqual("42", result.ErrorCodes[0]);
                Assert.IsTrue(result.ErrorDescription.Contains("more_detailed_error_message"));
            }
        }
예제 #4
0
        internal static MsalTokenResponse CreateMsalResponseFromWamResponse(
            IWebTokenRequestResultWrapper wamResponse,
            IWamPlugin wamPlugin,
            string clientId,
            ICoreLogger logger,
            bool isInteractive)
        {
            string internalErrorCode = null;
            string errorMessage;
            string errorCode;

            switch (wamResponse.ResponseStatus)
            {
            case WebTokenRequestStatus.Success:
                logger.Info("WAM response status success");
                return(wamPlugin.ParseSuccessfullWamResponse(wamResponse.ResponseData[0], out _));

            // Account Switch occurs when a login hint is passed to WAM but the user chooses a different account for login.
            // MSAL treats this as a success scenario
            case WebTokenRequestStatus.AccountSwitch:
                logger.Info("WAM response status account switch. Treating as success");
                return(wamPlugin.ParseSuccessfullWamResponse(wamResponse.ResponseData[0], out _));

            case WebTokenRequestStatus.UserInteractionRequired:
                errorCode =
                    wamPlugin.MapTokenRequestError(wamResponse.ResponseStatus, wamResponse.ResponseError?.ErrorCode ?? 0, isInteractive);
                internalErrorCode = (wamResponse.ResponseError?.ErrorCode ?? 0).ToString(CultureInfo.InvariantCulture);
                errorMessage      = WamErrorPrefix +
                                    $"Wam plugin {wamPlugin.GetType()}" +
                                    $" Error code: {internalErrorCode}" +
                                    $" Error Message: " + wamResponse.ResponseError?.ErrorMessage;
                break;

            case WebTokenRequestStatus.UserCancel:
                errorCode    = MsalError.AuthenticationCanceledError;
                errorMessage = MsalErrorMessage.AuthenticationCanceled;
                break;

            case WebTokenRequestStatus.ProviderError:
                errorCode =
                    wamPlugin.MapTokenRequestError(wamResponse.ResponseStatus, wamResponse.ResponseError?.ErrorCode ?? 0, isInteractive);
                errorMessage =
                    $"{WamErrorPrefix} {wamPlugin.GetType()} \n" +
                    $" Error Code: {errorCode} \n" +
                    $" Error Message: {wamResponse.ResponseError?.ErrorMessage} \n" +
                    $" Possible causes: \n " +
                    $"- Invalid redirect uri - ensure you have configured the following url in the AAD portal App Registration: {GetExpectedRedirectUri(clientId)} \n" +
                    $"- No Internet connection \n" +
                    $"Please see https://aka.ms/msal-net-wam for details about Windows Broker integration";

                internalErrorCode = (wamResponse.ResponseError?.ErrorCode ?? 0).ToString(CultureInfo.InvariantCulture);
                break;

            default:
                errorCode         = MsalError.UnknownBrokerError;
                internalErrorCode = wamResponse.ResponseError.ErrorCode.ToString(CultureInfo.InvariantCulture);
                errorMessage      = $"Unknown WebTokenRequestStatus {wamResponse.ResponseStatus} (internal error code {internalErrorCode})";
                break;
            }

            return(new MsalTokenResponse()
            {
                Error = errorCode,
                ErrorCodes = internalErrorCode != null ? new[] { internalErrorCode } : null,
                ErrorDescription = errorMessage
            });
        }