private Intent GetInteractiveBrokerIntent(IDictionary <string, string> brokerPayload, Intent brokerIntent)
        {
            ValidateBrokerRedirectURI(brokerPayload);
            BrokerRequest request = new BrokerRequest
            {
                Authority        = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.Authority),
                Scopes           = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.Scope),
                RedirectUri      = GetEncodedRedirectUri(GetValueFromBrokerPayload(brokerPayload, BrokerParameter.RedirectUri)),
                ClientId         = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.ClientId),
                ClientAppName    = Application.Context.PackageName,
                ClientAppVersion = Application.Context.PackageManager.GetPackageInfo(Application.Context.PackageName, PackageInfoFlags.MatchAll).VersionName,
                ClientVersion    = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.ClientVersion),
                CorrelationId    = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.CorrelationId),
                Prompt           = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.Prompt).ToUpperInvariant()
            };

            brokerIntent.PutExtra(BrokerConstants.BrokerRequestV2, JsonHelper.SerializeToJson(request));

            return(brokerIntent);
        }
        public static BrokerRequest FromInteractiveParameters(
            AuthenticationRequestParameters authenticationRequestParameters,
            AcquireTokenInteractiveParameters acquireTokenInteractiveParameters)
        {
            BrokerRequest br     = FromAuthenticationParameters(authenticationRequestParameters);
            var           prompt = acquireTokenInteractiveParameters.Prompt;

            if (prompt == Client.Prompt.NoPrompt || prompt == Client.Prompt.NotSpecified)
            {
                br.Prompt = Client.Prompt.SelectAccount.PromptValue.ToUpperInvariant();
            }
            else
            {
                br.Prompt = prompt.PromptValue.ToUpperInvariant();
            }

            br.UserName = acquireTokenInteractiveParameters.LoginHint;

            return(br);
        }
        public async Task <string> GetBrokerAuthTokenSilentlyAsync(BrokerRequest brokerRequest, Activity callerActivity)
        {
            CheckForBrokerAccountInfoInAccountManager(brokerRequest, callerActivity);
            Bundle silentOperationBundle = CreateSilentBrokerBundle(brokerRequest);

            silentOperationBundle.PutString(BrokerConstants.BrokerAccountManagerOperationKey, BrokerConstants.AcquireTokenSilent);

            IAccountManagerFuture result = _androidAccountManager.AddAccount(BrokerConstants.BrokerAccountType,
                                                                             BrokerConstants.AuthtokenType,
                                                                             null,
                                                                             silentOperationBundle,
                                                                             null,
                                                                             null,
                                                                             GetPreferredLooper(callerActivity));

            if (result != null)
            {
                Bundle bundleResult = (Bundle)await result.GetResultAsync(
                    AccountManagerTimeoutSeconds,
                    TimeUnit.Seconds)
                                      .ConfigureAwait(false);

                string responseJson = bundleResult.GetString(BrokerConstants.BrokerResultV2);

                bool success = bundleResult.GetBoolean(BrokerConstants.BrokerRequestV2Success);
                _logger.Info($"Android Broker Silent call result - success? {success}.");

                if (!success)
                {
                    _logger.Warning($"Android Broker Silent call failed. " +
                                    $"This usually means that the RT cannot be refreshed and interaction is required. " +
                                    $"BundleResult: {bundleResult} Result string: {responseJson}");
                }

                // upstream logic knows how to extract potential errors from this result
                return(responseJson);
            }

            _logger.Info("Android Broker didn't return any results.");
            return(null);
        }
        private async Task <Intent> GetIntentForInteractiveBrokerRequestAsync(BrokerRequest brokerRequest)
        {
            try
            {
                // Callback is not passed since it is making a blocking call to get
                // intent. Activity needs to be launched from calling app
                // to get the calling app's meta data if needed at BrokerActivity.

                Bundle addAccountOptions = new Bundle();
                addAccountOptions.PutString(BrokerConstants.BrokerAccountManagerOperationKey, BrokerConstants.GetIntentForInteractiveRequest);

                Bundle accountManagerResult = await PerformAccountManagerOperationAsync(addAccountOptions).ConfigureAwait(false);

                return(CreateIntentFromInteractiveBundle(accountManagerResult, brokerRequest));
            }
            catch
            {
                _logger.Error("[Android broker] Error when trying to acquire intent for broker authentication. ");
                throw;
            }
        }
        private async Task <MsalTokenResponse> AcquireTokenSilentViaBrokerAsync(BrokerRequest brokerRequest)
        {
            // Don't send silent background request if account information is not provided

            using (_logger.LogMethodDuration())
            {
                _logger.Verbose("User is specified for silent token request. Starting silent Android broker request. ");
                string silentResult = await _brokerHelper.GetBrokerAuthTokenSilentlyAsync(brokerRequest, _parentActivity).ConfigureAwait(false);

                if (!string.IsNullOrEmpty(silentResult))
                {
                    return(MsalTokenResponse.CreateFromAndroidBrokerResponse(silentResult, brokerRequest.CorrelationId));
                }

                return(new MsalTokenResponse
                {
                    Error = MsalError.BrokerResponseReturnedError,
                    ErrorDescription = "Unknown Android broker error. Failed to acquire token silently from the broker. " + MsalErrorMessage.AndroidBrokerCannotBeInvoked,
                });
            }
        }
Ejemplo n.º 6
0
        public BrokerRequest UpdateBrokerRequestWithAccountData(string accountData, BrokerRequest brokerRequest)
        {
            if (string.IsNullOrEmpty(accountData))
            {
                _logger.Info("[Android broker] Android account manager didn't return any accounts. ");
                throw new MsalUiRequiredException(MsalError.NoAndroidBrokerAccountFound, MsalErrorMessage.NoAndroidBrokerAccountFound);
            }

            string username       = brokerRequest.UserName;
            string homeAccountId  = brokerRequest.HomeAccountId;
            string localAccountId = brokerRequest.LocalAccountId;

            dynamic AccountDataList = JArray.Parse(accountData);

            foreach (JObject account in AccountDataList)
            {
                var accountInfo = account[BrokerResponseConst.Account];
                var accountInfoHomeAccountID  = accountInfo[BrokerResponseConst.HomeAccountId]?.ToString();
                var accountInfoLocalAccountID = accountInfo[BrokerResponseConst.LocalAccountId]?.ToString();

                if (string.Equals(accountInfo[BrokerResponseConst.UserName].ToString(), username, StringComparison.OrdinalIgnoreCase))
                {
                    // TODO: broker request should be immutable!
                    brokerRequest.HomeAccountId  = accountInfoHomeAccountID;
                    brokerRequest.LocalAccountId = accountInfoLocalAccountID;
                    _logger.Info("[Android broker] Found broker account in Android account manager using the provided login hint. ");
                    return(brokerRequest);
                }

                if (string.Equals(accountInfoHomeAccountID, homeAccountId, StringComparison.Ordinal) &&
                    string.Equals(accountInfoLocalAccountID, localAccountId, StringComparison.Ordinal))
                {
                    _logger.Info("[Android broker] Found broker account in Android account manager using the provided account. ");
                    return(brokerRequest);
                }
            }

            _logger.Info("[Android broker] The requested account does not exist in the Android account manager. ");
            throw new MsalUiRequiredException(MsalError.NoAndroidBrokerAccountFound, MsalErrorMessage.NoAndroidBrokerAccountFound);
        }
        public async Task <MsalTokenResponse> AcquireTokenSilentAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            AcquireTokenSilentParameters acquireTokenSilentParameters)
        {
            CheckPowerOptimizationStatus();

            BrokerRequest brokerRequest = BrokerRequest.FromSilentParameters(
                authenticationRequestParameters, acquireTokenSilentParameters);

            try
            {
                await InitiateBrokerHandshakeAsync().ConfigureAwait(false);

                return(await AcquireTokenSilentViaBrokerAsync(brokerRequest).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                _logger.ErrorPiiWithPrefix(ex, "[Android broker] Android broker silent invocation failed. ");
                _brokerHelper.HandleBrokerOperationError(ex);
                throw;
            }
        }
        public async Task <MsalTokenResponse> AcquireTokenSilentAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            AcquireTokenSilentParameters acquireTokenSilentParameters)
        {
            BrokerRequest brokerRequest = BrokerRequest.FromSilentParameters(
                authenticationRequestParameters, acquireTokenSilentParameters);

            try
            {
                await _brokerHelper.InitiateBrokerHandshakeAsync(_parentActivity).ConfigureAwait(false);

                var androidBrokerTokenResponse = await AcquireTokenSilentViaBrokerAsync(brokerRequest).ConfigureAwait(false);

                return(androidBrokerTokenResponse);
            }
            catch (Exception ex)
            {
                _logger.ErrorPiiWithPrefix(ex, "Android broker silent invocation failed. ");
                HandleBrokerOperationError(ex);
                throw;
            }
        }
Ejemplo n.º 9
0
        private async Task <IReadOnlyList <IAccount> > GetAccountsInternalAsync(string clientID, string redirectUri)
        {
            BrokerRequest brokerRequest = new BrokerRequest()
            {
                ClientId = clientID, RedirectUri = new Uri(redirectUri)
            };

            try
            {
                await InitiateBrokerHandShakeAsync().ConfigureAwait(false);

                var accountData = await GetBrokerAccountDataAsync(brokerRequest).ConfigureAwait(false);

                return(_brokerHelper.ExtractBrokerAccountsFromAccountData(accountData));
            }
            catch (Exception ex)
            {
                _logger.Error("[Android broker] Failed to get accounts from the broker. ");
                _brokerHelper.HandleBrokerOperationError(ex);
                throw;
            }
        }
Ejemplo n.º 10
0
        private Intent CreateInteractiveBrokerIntent(BrokerRequest brokerRequest, Bundle bundleResult)
        {
            string packageName = bundleResult.GetString("broker.package.name");
            string className   = bundleResult.GetString("broker.activity.name");

            Intent brokerIntent = new Intent();

            brokerIntent.SetPackage(packageName);
            brokerIntent.SetClassName(
                packageName,
                className
                );

            brokerIntent.PutExtras(bundleResult);
            brokerIntent.PutExtra(BrokerConstants.NegotiatedBPVersionKey, _negotiatedBrokerProtocolKey);

            var interactiveIntent = brokerIntent.PutExtras(CreateInteractiveBrokerBundle(brokerRequest));

            interactiveIntent.PutExtra(BrokerConstants.CallerInfoUID, Binder.CallingUid);

            return(interactiveIntent);
        }
        public async Task <IReadOnlyList <IAccount> > GetAccountsAsync(
            string clientId,
            string redirectUri,
            AuthorityInfo authorityInfo,
            ICacheSessionManager cacheSessionManager,
            IInstanceDiscoveryManager instanceDiscoveryManager)
        {
            using (_logger.LogMethodDuration())
            {
                if (!IsBrokerInstalledAndInvokable())
                {
                    _logger.Warning("[Android broker] Broker is either not installed or is not reachable so no accounts will be returned. ");
                    return(new List <IAccount>());
                }

                BrokerRequest brokerRequest = new BrokerRequest()
                {
                    ClientId = clientId, RedirectUri = new Uri(redirectUri)
                };

                try
                {
                    await InitiateBrokerHandshakeAsync().ConfigureAwait(false);

                    var accounts = GetBrokerAccounts(brokerRequest);

                    return(_brokerHelper.ExtractBrokerAccountsFromAccountData(accounts));
                }
                catch (Exception ex)
                {
                    _logger.Error("[Android broker] Failed to get Android broker accounts from the broker. ");
                    _brokerHelper.HandleBrokerOperationError(ex);
                    throw;
                }
            }
        }
        private Bundle GetSilentBrokerBundle(IDictionary <string, string> brokerPayload)
        {
            ValidateBrokerRedirectURI(brokerPayload);
            Bundle bundle = new Bundle();

            BrokerRequest request = new BrokerRequest
            {
                Authority        = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.Authority),
                Scopes           = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.Scope),
                RedirectUri      = GetEncodedRedirectUri(GetValueFromBrokerPayload(brokerPayload, BrokerParameter.RedirectUri)),
                ClientId         = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.ClientId),
                ClientAppName    = Application.Context.PackageName,
                ClientAppVersion = Application.Context.PackageManager.GetPackageInfo(Application.Context.PackageName, PackageInfoFlags.MatchAll).VersionName,
                ClientVersion    = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.ClientVersion),
                CorrelationId    = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.CorrelationId),
                HomeAccountId    = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.HomeAccountId),
                LocalAccountId   = GetValueFromBrokerPayload(brokerPayload, BrokerParameter.LocalAccountId)
            };

            bundle.PutString(BrokerConstants.BrokerRequestV2, JsonHelper.SerializeToJson(request));
            bundle.PutInt(BrokerConstants.CallerInfoUID, Binder.CallingUid);

            return(bundle);
        }
        private Intent CreateIntentFromInteractiveBundle(Bundle accountManagerResult, BrokerRequest brokerRequest)
        {
            if (accountManagerResult == null)
            {
                _logger.Info("[Android broker] Android account manager didn't return any results for interactive broker request. ");
            }

            Intent interactiveIntent = (Intent)accountManagerResult?.GetParcelable(AccountManager.KeyIntent);

            // Validate that the intent was created successfully.
            if (interactiveIntent != null)
            {
                _logger.Info("[Android broker] Intent created from BundleResult is not null. Starting interactive broker request. ");
                // Need caller info UID for broker communication
                interactiveIntent.PutExtra(BrokerConstants.CallerInfoUID, Binder.CallingUid);
            }
            else
            {
                _logger.Info("[Android broker] Intent created from BundleResult is null. ");
                throw new MsalClientException(MsalError.NullIntentReturnedFromAndroidBroker, MsalErrorMessage.NullIntentReturnedFromBroker);
            }

            return(CreateInteractiveBrokerIntent(brokerRequest, interactiveIntent));
        }
        public async Task <Intent> GetIntentForInteractiveBrokerRequestAsync(BrokerRequest brokerRequest, Activity callerActivity)
        {
            Intent intent = null;

            try
            {
                IAccountManagerFuture result = null;
                // Callback is not passed since it is making a blocking call to get
                // intent. Activity needs to be launched from calling app
                // to get the calling app's metadata if needed at BrokerActivity.

                Bundle addAccountOptions = new Bundle();
                addAccountOptions.PutString(BrokerConstants.BrokerAccountManagerOperationKey, BrokerConstants.GetIntentForInteractiveRequest);

                result = _androidAccountManager.AddAccount(BrokerConstants.BrokerAccountType,
                                                           BrokerConstants.AuthtokenType,
                                                           null,
                                                           addAccountOptions,
                                                           null,
                                                           null,
                                                           GetPreferredLooper(callerActivity));

                if (result == null)
                {
                    _logger.Info("Android account manager didn't return any results for interactive broker request. ");
                }

                Bundle bundleResult = null;

                try
                {
                    bundleResult = (Bundle)await result.GetResultAsync(
                        AccountManagerTimeoutSeconds,
                        TimeUnit.Seconds)
                                   .ConfigureAwait(false);
                }
                catch (OperationCanceledException ex)
                {
                    _logger.Error("An error occurred when trying to communicate with account manager: " + ex.Message);
                }
                catch (Exception ex)
                {
                    throw new MsalClientException(MsalError.BrokerApplicationRequired, MsalErrorMessage.AndroidBrokerCannotBeInvoked, ex);
                }

                intent = (Intent)bundleResult?.GetParcelable(AccountManager.KeyIntent);

                //Validate that the intent was created successfully.
                if (intent != null)
                {
                    _logger.Info("Intent created from BundleResult is not null. Starting interactive broker request. ");
                    // Need caller info UID for broker communication
                    intent.PutExtra(BrokerConstants.CallerInfoUID, Binder.CallingUid);
                }
                else
                {
                    _logger.Info("Intent created from BundleResult is null. ");
                    throw new MsalClientException(MsalError.NullIntentReturnedFromAndroidBroker, MsalErrorMessage.NullIntentReturnedFromBroker);
                }

                intent = GetInteractiveBrokerIntent(brokerRequest, intent);
            }
            catch
            {
                _logger.Error("Error when trying to acquire intent for broker authentication. ");
                throw;
            }

            return(intent);
        }