示例#1
0
        public string GetProtocolKeyFromHandShakeResult(Bundle bundleResult)
        {
            var negotiatedBrokerProtocalKey = bundleResult?.GetString(BrokerConstants.NegotiatedBPVersionKey);

            if (!string.IsNullOrEmpty(negotiatedBrokerProtocalKey))
            {
                _logger.Info("[Android broker] Using broker protocol version: " + negotiatedBrokerProtocalKey);
                return(negotiatedBrokerProtocalKey);
            }

            dynamic errorResult      = JObject.Parse(bundleResult?.GetString(BrokerConstants.BrokerResultV2));
            string  errorCode        = null;
            string  errorDescription = null;

            if (!string.IsNullOrEmpty(errorResult))
            {
                errorCode = errorResult[BrokerResponseConst.BrokerErrorCode]?.ToString();
                string errorMessage = errorResult[BrokerResponseConst.BrokerErrorMessage]?.ToString();
                errorDescription = $"[Android broker] An error occurred during hand shake with the broker. Error: {errorCode} Error Message: {errorMessage}";
            }
            else
            {
                errorCode        = BrokerConstants.BrokerUnknownErrorCode;
                errorDescription = "[Android broker] An error occurred during hand shake with the broker, no detailed error information was returned. ";
            }

            _logger.Error(errorDescription);
            throw new MsalClientException(errorCode, errorDescription);
        }
        private async Task OnBeforeAccessAsync(TokenCacheNotificationArgs args)
        {
            _logger.Verbose($"OnBeforeAccessAsync - before getting the lock " + _semaphoreSlim.CurrentCount);

            // prevent other threads / background tasks from reading the file
            await _semaphoreSlim.WaitAsync().ConfigureAwait(true);

            _logger.Verbose($"OnBeforeAccessAsync - acquired the lock");

            IStorageFile cacheFile = await ApplicationData.Current.LocalFolder.TryGetItemAsync(CacheFileName) as IStorageFile;

            if (cacheFile != null)
            {
                byte[] decryptedBlob;
                try
                {
                    decryptedBlob = await ReadAndDecryptAsync(cacheFile).ConfigureAwait(true);
                }
                catch (Exception ex)
                {
                    _logger.Error("UWP cache file could not be loaded. Using in-memory cache only.");
                    _logger.ErrorPii(ex);

                    return;
                }

                if (decryptedBlob != null)
                {
                    args.TokenCache.DeserializeMsalV3(decryptedBlob);
                }
            }
        }
        public async Task <IEnumerable <IAccount> > GetAccountsAsync(string clientID, string redirectUri)
        {
            using (_logger.LogMethodDuration())
            {
                if (!IsBrokerInstalledAndInvokable())
                {
                    _logger.Warning("Android 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 _brokerHelper.InitiateBrokerHandshakeAsync(_parentActivity).ConfigureAwait(false);

                    return(_brokerHelper.GetBrokerAccountsInAccountManager(brokerRequest));
                }
                catch (Exception ex)
                {
                    _logger.Error("Failed to get Android broker accounts from the broker. ");
                    HandleBrokerOperationError(ex);
                    throw;
                }
            }
        }
        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 = (Bundle)await result.GetResultAsync(
                    AccountManagerTimeoutSeconds,
                    TimeUnit.Seconds)
                                      .ConfigureAwait(false);

                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);
        }
        public async Task <MsalTokenResponse> AcquireTokenInteractiveAsync(
            AuthenticationRequestParameters authenticationRequestParameters,
            AcquireTokenInteractiveParameters acquireTokenInteractiveParameters)
        {
            MsalTokenResponse msalTokenResponse = null;

            //need to provide a handle
            if (_parentHandle == IntPtr.Zero)
            {
                throw new MsalClientException(
                          "window_handle_required",
                          "Public Client applications wanting to use WAM need to provide their window handle. Console applications can use GetConsoleWindow Windows API for this.");
            }

            //if OperatingSystemAccount is passed then we use the user signed-in on the machine
            if (PublicClientApplication.IsOperatingSystemAccount(authenticationRequestParameters.Account))
            {
                return(await AcquireTokenInteractiveDefaultUserAsync(authenticationRequestParameters, acquireTokenInteractiveParameters).ConfigureAwait(false));
            }

            var cancellationToken = authenticationRequestParameters.RequestContext.UserCancellationToken;

            _logger.Verbose("[WamBroker] Using Windows account picker.");

            using (var core = new NativeInterop.Core())
                using (var authParams = WamAdapters.GetCommonAuthParameters(authenticationRequestParameters, _wamOptions.MsaPassthrough))
                {
                    //Login Hint
                    string loginHint = authenticationRequestParameters.LoginHint ?? authenticationRequestParameters?.Account?.Username;

                    _logger.Verbose("[WamBroker] AcquireTokenInteractive - login hint provided? " + string.IsNullOrEmpty(loginHint));

                    using (var result = await core.SignInInteractivelyAsync(
                               _parentHandle,
                               authParams,
                               authenticationRequestParameters.CorrelationId.ToString("D"),
                               loginHint,
                               cancellationToken).ConfigureAwait(false))
                    {
                        if (result.IsSuccess)
                        {
                            msalTokenResponse = WamAdapters.ParseRuntimeResponse(result, authenticationRequestParameters, _logger);
                            _logger.Verbose("[WamBroker] Successfully retrieved token.");
                        }
                        else
                        {
                            _logger.Error($"[WamBroker] Could not login interactively. {result.Error}");
                            WamAdapters.ThrowExceptionFromWamError(result, authenticationRequestParameters, _logger);
                        }
                    }
                }

            return(msalTokenResponse);
        }
示例#6
0
        public Intent GetIntentForInteractiveBrokerRequest(IDictionary <string, string> brokerPayload, 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 = (Bundle)result?.Result;
                // Broker should throw OperationCanceledException if token is not available
                intent = (Intent)bundleResult?.GetParcelable(AccountManager.KeyIntent);

                //Validate that the intent was created succsesfully.
                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 MsalException(MsalError.NullIntentReturnedFromAndroidBroker, MsalErrorMessage.NullIntentReturnedFromBroker);
                }

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

            return(intent);
        }
示例#7
0
        private void checkPackageForPowerOptimization(string package)
        {
            var powerManager = PowerManager.FromContext(Application.Context);

            //Power optimization checking was added in API 23
            if ((int)Build.VERSION.SdkInt >= (int)BuildVersionCodes.M &&
                powerManager.IsDeviceIdleMode &&
                !powerManager.IsIgnoringBatteryOptimizations(package))
            {
                _logger.Error("Power optimization detected for the application: " + package + " and the device is in doze mode or the app is in standby. \n" +
                              "Please disable power optimizations for this application to authenticate.");
            }
        }
示例#8
0
        public async Task <ActionResult> Index()
        {
            try
            {
                Thread.Sleep(2000);
                var response = await _searchApi.Get("api/v1/search");

                return(await GetResponse(response));
            }
            catch (HttpResponseException hrex)
            {
                _logger.Error(hrex);
                return(HttpNotFound(string.Format("An error occured:", hrex.Message)));
            }
        }
示例#9
0
        private bool CheckForEndUrl(Uri url)
        {
            bool readyToClose = false;

            if (url.Authority.Equals(_endUri.Authority, StringComparison.OrdinalIgnoreCase) &&
                url.AbsolutePath.Equals(_endUri.AbsolutePath))
            {
                _logger.Info("Redirect Uri was reached. Stopping webview navigation...");
                _result      = AuthorizationResult.FromUri(url.OriginalString);
                readyToClose = true;
            }

            if (!readyToClose &&
                !url.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) &&
                !url.AbsoluteUri.Equals("about:blank", StringComparison.OrdinalIgnoreCase) &&
                !url.Scheme.Equals("javascript", StringComparison.OrdinalIgnoreCase))
            {
                _logger.Error($"Redirection to non-HTTPS scheme ({url.Scheme}) found! Webview will fail...");

                _result = AuthorizationResult.FromStatus(
                    AuthorizationStatus.ErrorHttp,
                    MsalError.NonHttpsRedirectNotSupported,
                    MsalErrorMessage.NonHttpsRedirectNotSupported);

                readyToClose = true;
            }

            if (readyToClose)
            {
                // This should close the dialog
                DialogResult = DialogResult.OK;
            }

            return(readyToClose);
        }
示例#10
0
        private void OnBeforeAccess(TokenCacheNotificationArgs args)
        {
            IStorageFile cacheFile = ApplicationData.Current.LocalFolder.TryGetItemAsync(CacheFileName)
                                     .AsTask().GetAwaiter().GetResult() as IStorageFile;


            if (cacheFile != null)
            {
                byte[] decryptedBlob = null;

                try
                {
                    decryptedBlob = ReadAndDecrypt(cacheFile);
                }
                catch (Exception ex)
                {
                    _logger.Error("The UWP cache file could not be decrypted. Corrupted files cannot be restored. Deleting the file.");
                    _logger.ErrorPii(ex);

                    cacheFile.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask().GetAwaiter().GetResult();
                    return;
                }

                if (decryptedBlob != null)
                {
                    args.TokenCache.DeserializeMsalV3(decryptedBlob);
                }
            }
        }
        public override void Handle(ExceptionHandlerContext context)
        {
            var timer = ((Stopwatch)context.Request.Properties["logtimer"]);

            timer.Stop();

            var exception     = context.Exception;
            var httpException = exception as HttpException;
            var logMessage    = new LogMessage
            {
                RequestUri    = context.Request.RequestUri.LocalPath,
                RequestMethod = context.Request.Method.Method,
                ElapsedMls    = timer.ElapsedMilliseconds.ToString()
            };

            if (httpException != null)
            {
                context.Result = new ErrorResultMessage(context.Request,
                                                        (HttpStatusCode)httpException.GetHttpCode(), httpException.Message);
                return;
            }

            logMessage.Message    = exception.StackTrace;
            logMessage.StatusCode = (int)HttpStatusCode.InternalServerError;
            _logger.Error(logMessage.ToString());

            context.Result = new ErrorResultMessage(context.Request, HttpStatusCode.InternalServerError,
                                                    exception.Message);
        }
示例#12
0
        private static void RemoveEntriesWithMatchingName(
            ICoreLogger logger,
            string clientId,
            string displayableId,
            IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCache)
        {
            if (string.IsNullOrEmpty(displayableId))
            {
                logger.Error(MsalErrorMessage.InternalErrorCacheEmptyUsername);
                return;
            }

            var keysToRemove = new List <AdalTokenCacheKey>();

            foreach (KeyValuePair <AdalTokenCacheKey, AdalResultWrapper> kvp in adalCache)
            {
                string cachedAccountDisplayableId = kvp.Key.DisplayableId;
                string cachedClientId             = kvp.Key.ClientId;

                if (string.Equals(displayableId, cachedAccountDisplayableId, StringComparison.OrdinalIgnoreCase) &&
                    string.Equals(clientId, cachedClientId, StringComparison.OrdinalIgnoreCase))
                {
                    keysToRemove.Add(kvp.Key);
                }
            }

            foreach (AdalTokenCacheKey key in keysToRemove)
            {
                adalCache.Remove(key);
            }
        }
        public async Task <MsalTokenResponse> AcquireTokenUsingBrokerAsync(Dictionary <string, string> brokerPayload)
        {
            _androidBrokerTokenResponse = null;
            _correlationId = AndroidBrokerHelper.GetValueFromBrokerPayload(brokerPayload, BrokerParameter.CorrelationId);
            //Need to disable warning for non awaited async call.
            try
            {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                new TaskFactory().StartNew(() => AcquireTokenInternalAsync(brokerPayload));
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
            catch (Exception ex)
            {
                _logger.Error("Broker Operation Failed to complete.");
                if (ex is MsalException)
                {
                    throw;
                }
                else
                {
                    throw new MsalException(MsalError.AndroidBrokerOperationFailed, ex.Message, ex);
                }
            }

            await _readyForResponse.WaitAsync().ConfigureAwait(false);

            return(_androidBrokerTokenResponse);
        }
        public static MsalRefreshTokenCacheItem GetAdalEntryForMsal(
            ICoreLogger logger,
            ILegacyCachePersistence legacyCachePersistence,
            IEnumerable <string> environmentAliases,
            string clientId,
            string upn,
            string uniqueId)
        {
            IEnumerable <MsalRefreshTokenCacheItem> adalRts = GetAllAdalEntriesForMsal(
                logger,
                legacyCachePersistence,
                environmentAliases,
                clientId,
                upn,
                uniqueId);

            IEnumerable <IGrouping <string, MsalRefreshTokenCacheItem> > rtGroupsByEnv = adalRts.GroupBy(rt => rt.Environment.ToLowerInvariant());

            // if we have more than 1 RT per env, there is smth wrong with the ADAL cache
            if (rtGroupsByEnv.Any(g => g.Count() > 1))
            {
                //Due to the fact that there is a problem with the ADAL cache that causes this exception, The ADAL cache will be removed when
                //this exception is triggered so that users can sign in interactivly and repopulate the cache.
                IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCache =
                    AdalCacheOperations.Deserialize(logger, legacyCachePersistence.LoadCache());

                adalCache.Clear();
                logger.Error(MsalErrorMessage.InvalidAdalCacheMultipleRTs);
                legacyCachePersistence.WriteCache(AdalCacheOperations.Serialize(logger, adalCache));
                return(null);
            }

            return(adalRts.FirstOrDefault());
        }
        public async Task <IReadOnlyList <WebAccount> > FindAllWebAccountsAsync(WebAccountProvider provider, string clientID)
        {
            using (_logger.LogBlockDuration("WAM:FindAllWebAccountsAsync:"))
            {
                // Win 10 RS3 release and above
                if (!ApiInformation.IsMethodPresent(
                        "Windows.Security.Authentication.Web.Core.WebAuthenticationCoreManager",
                        "FindAllAccountsAsync"))
                {
                    _logger.Info("[WamProxy] FindAllAccountsAsync method does not exist (it was introduced in Win 10 RS3). " +
                                 "Returning 0 broker accounts. ");
                    return(Enumerable.Empty <WebAccount>().ToList());
                }

                FindAllAccountsResult findResult = await WebAuthenticationCoreManager.FindAllAccountsAsync(provider, clientID);

                // This is expected to happen with the MSA provider, which does not allow account listing
                if (findResult.Status != FindAllWebAccountsStatus.Success)
                {
                    var error = findResult.ProviderError;
                    _logger.Error($"[WAM Proxy] WebAuthenticationCoreManager.FindAllAccountsAsync failed " +
                                  $" with error code {error.ErrorCode} error message {error.ErrorMessage} and status {findResult.Status}");

                    return(Enumerable.Empty <WebAccount>().ToList());
                }

                _logger.Info($"[WAM Proxy] FindAllWebAccountsAsync returning {findResult.Accounts.Count()} WAM accounts");
                return(findResult.Accounts);
            }
        }
示例#16
0
        public async Task <MsalTokenResponse> AcquireTokenUsingBrokerAsync(Dictionary <string, string> brokerPayload)
        {
            s_androidBrokerTokenResponse = null;
            s_correlationId = AndroidBrokerHelper.GetValueFromBrokerPayload(brokerPayload, BrokerParameter.CorrelationId);

            try
            {
                // This task will kick off the broker and will block on the _readyForResponse semaphore
                // When the broker activity ends, SetBrokerResult is called, which releases the semaphore.
                await AcquireTokenInternalAsync(brokerPayload).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.Error("Broker Operation Failed to complete. In order to perform brokered authentication on android" +
                              " you need to ensure that you have installed either Intune Company Portal (Version 5.0.4689.0 or greater) or Microsoft Authenticator (6.2001.0140 or greater).");
                if (ex is MsalException)
                {
                    throw;
                }
                else
                {
                    throw new MsalClientException(MsalError.AndroidBrokerOperationFailed, ex.Message, ex);
                }
            }

            return(s_androidBrokerTokenResponse);
        }
        /// <summary>
        /// CreateRefreshToken async
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async override Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            try
            {
                //Create(context);
                // var clientid = context.Ticket.Properties.Dictionary["as:client_id"];

                object owinCollection;
                context.OwinContext.Environment.TryGetValue("Microsoft.Owin.Form#collection", out owinCollection);

                var grantType = ((FormCollection)owinCollection)?.GetValues("grant_type").FirstOrDefault();
                var clientId  = ((FormCollection)owinCollection)?.GetValues("client_id").FirstOrDefault();

                if (grantType == null)
                {
                    return;
                }

                if (clientId == null)
                {
                    return;
                }

                var refreshTokenId = Guid.NewGuid().ToString("n");

                var refreshTokenLifeTime = context.OwinContext.Get <string>("as:clientRefreshTokenLifeTime");

                var token = new RefreshTokenModel()
                {
                    RefToken   = Utility.GetHash(refreshTokenId),
                    ClientId   = clientId,
                    UserName   = context.Ticket.Identity.Name,
                    IssuedUtc  = DateTime.UtcNow,
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime))
                };

                context.Ticket.Properties.IssuedUtc  = token.IssuedUtc;
                context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;
                token.ProtectedTicket = context.SerializeTicket();

                var existingToken = await _refreshTokenService.GetByClientIdAndUserNameAsync(token.ClientId, token.UserName);

                if (existingToken != null)
                {
                    await _refreshTokenService.DeleteAsync(existingToken.Id);
                }

                await _refreshTokenService.InsertAsync(token);

                context.SetToken(refreshTokenId);
            }
            catch (Exception ex)
            {
                _logger.Error(GetType(), ex, "RefreshTokenProvider/CreateAsync");
                throw ex;
            }
        }
示例#18
0
        public bool IsBrokerInstalledAndInvokable()
        {
            using (_logger.LogMethodDuration())
            {
                if (_uIParent?.CallerViewController == null)
                {
                    _logger.Error(iOSBrokerConstants.CallerViewControllerIsNullCannotInvokeBroker);
                    throw new MsalClientException(MsalError.UIViewControllerRequiredForiOSBroker, MsalErrorMessage.UIViewControllerIsRequiredToInvokeiOSBroker);
                }

                bool canStartBroker = false;

                _uIParent.CallerViewController.InvokeOnMainThread(() =>
                {
                    if (IsBrokerInstalled(BrokerParameter.UriSchemeBrokerV3))
                    {
                        _logger.Info(iOSBrokerConstants.iOSBrokerv3Installed);
                        _brokerV3Installed = true;
                        canStartBroker     = true;
                    }
                });

                if (!canStartBroker)
                {
                    _uIParent.CallerViewController.InvokeOnMainThread(() =>
                    {
                        if (IsBrokerInstalled(BrokerParameter.UriSchemeBrokerV2))
                        {
                            _logger.Info(iOSBrokerConstants.iOSBrokerv2Installed);
                            canStartBroker = true;
                        }
                    });
                }

                if (!canStartBroker)
                {
                    _logger.Info(iOSBrokerConstants.CanInvokeBrokerReturnsFalseMessage);
                }

                return(canStartBroker);
            }
        }
        private static byte[] CreateAndStoreBrokerKey(ICoreLogger logger)
        {
            logger.Info("CreateAndStoreBrokerKey - creating a new key");

            byte[] brokerKey;
            byte[] rawBytes;
            using (AesManaged algo = CreateSymmetricAlgorith(null))
            {
                algo.GenerateKey();
                rawBytes = algo.Key;
            }

            NSData byteData = NSData.FromArray(rawBytes);

            var recordToAdd = new SecRecord(SecKind.GenericPassword)
            {
                Generic     = NSData.FromString(iOSBrokerConstants.LocalSettingsContainerName),
                Service     = iOSBrokerConstants.BrokerKeyService,
                Account     = iOSBrokerConstants.BrokerKeyAccount,
                Label       = iOSBrokerConstants.BrokerKeyLabel,
                Comment     = iOSBrokerConstants.BrokerKeyComment,
                Description = iOSBrokerConstants.BrokerKeyStorageDescription,
                ValueData   = byteData
            };

            var result = SecKeyChain.Add(recordToAdd);

            if (result == SecStatusCode.DuplicateItem)
            {
                logger.Info("Could not add the broker key, a key already exists. Trying to delete it first.");
                var recordToRemove = new SecRecord(SecKind.GenericPassword)
                {
                    Service = iOSBrokerConstants.BrokerKeyService,
                    Account = iOSBrokerConstants.BrokerKeyAccount,
                };

                var removeResult = SecKeyChain.Remove(recordToRemove);
                logger.Info("Broker key removal result: " + removeResult);

                result = SecKeyChain.Add(recordToAdd);
                logger.Info("Broker key re-adding result: " + result);
            }

            if (result != SecStatusCode.Success)
            {
                logger.Error("Failed to save the broker key to keychain. Result " + result);
                throw new MsalClientException(
                          MsalError.BrokerKeySaveFailed,
                          MsalErrorMessage.iOSBrokerKeySaveFailed(result.ToString()));
            }

            brokerKey = byteData.ToArray();
            return(brokerKey);
        }
        public async Task <MsalTokenResponse> AcquireTokenUsingBrokerAsync(Dictionary <string, string> brokerPayload)
        {
            s_androidBrokerTokenResponse = null;
            s_correlationId = AndroidBrokerHelper.GetValueFromBrokerPayload(brokerPayload, BrokerParameter.CorrelationId);

            try
            {
                // This task will kick off the broker and will block on the _readyForResponse semaphore
                // When the broker activity ends, SetBrokerResult is called, which releases the semaphore.
                await AcquireTokenInternalAsync(brokerPayload).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.Error("Android broker authentication failed.");
                HandleBrokerOperationError(ex);
                throw;
            }

            return(s_androidBrokerTokenResponse);
        }
示例#21
0
 public void HandleBrokerOperationError(Exception ex)
 {
     _logger.Error(ex.Message);
     if (ex is MsalException)
     {
         throw ex;
     }
     else
     {
         throw new MsalClientException(MsalError.AndroidBrokerOperationFailed, ex.Message, ex);
     }
 }
        private static async Task <IBroker> GetInstalledBrokerAsync(CoreUIParent uIParent, ICoreLogger logger)
        {
            AndroidBrokerHelper brokerHelper = new AndroidBrokerHelper(Application.Context, logger);

            if (brokerHelper.IsBrokerInstalledAndInvokable(AuthorityType.Aad)) //authorityType is actually not used by the brokerHelper.IsBrokerInstalledAndInvokable
            {
                try
                {
                    var broker = new AndroidContentProviderBroker(uIParent, logger);
                    await broker.InitiateBrokerHandShakeAsync().ConfigureAwait(false);

                    s_installedBroker = BrokerType.ContentProvider;
                    logger.Info("[Android broker] Content provider broker is available and will be used.");
                    return(broker);
                }
                catch (Exception exContentProvider)
                {
                    logger.Error("[Android broker] Unable to communicate with the broker via Content Provider. Attempting to fall back to account manager communication.");
                    logger.Error(exContentProvider.Message);

                    try
                    {
                        var broker = new AndroidAccountManagerBroker(uIParent, logger);
                        await broker.InitiateBrokerHandshakeAsync().ConfigureAwait(false);

                        s_installedBroker = BrokerType.AccountManager;
                        logger.Info("[Android broker] Account manager broker is available and will be used.");
                        return(broker);
                    }
                    catch (Exception exAccountManager)
                    {
                        logger.Error("[Android broker] Unable to communicate with the broker via the Account manager.");
                        logger.Error(exAccountManager.Message);
                    }
                }
            }

            // Return a default broker in case no broker is installed to handle install URL
            return(new AndroidContentProviderBroker(uIParent, logger));
        }
示例#23
0
        public IHttpActionResult Get()
        {
            try
            {
                var list = _searchService.Get();

                if (list.Any())
                {
                    return(Json(list));
                }
                else
                {
                    _logger.Warn("No data content received from database.");
                    return(StatusCode(System.Net.HttpStatusCode.NoContent));
                }
            }
            catch (HttpResponseException hrex)
            {
                _logger.Error(hrex);
                return(StatusCode(System.Net.HttpStatusCode.InternalServerError));
            }
        }
示例#24
0
        /// <summary>
        /// CreateRefreshToken async
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async override Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            try
            {
                //Create(context);
                var clientid = context.Ticket.Properties.Dictionary["as:client_id"];

                if (string.IsNullOrEmpty(clientid))
                {
                    return;
                }

                var refreshTokenId = Guid.NewGuid().ToString("n");

                var refreshTokenLifeTime = context.OwinContext.Get <string>("as:clientRefreshTokenLifeTime");

                var token = new RefreshTokenModel()
                {
                    RefToken   = Utility.GetHash(refreshTokenId),
                    ClientId   = clientid,
                    UserName   = context.Ticket.Identity.Name,
                    IssuedUtc  = DateTime.UtcNow,
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime))
                };

                context.Ticket.Properties.IssuedUtc  = token.IssuedUtc;
                context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;

                token.ProtectedTicket = context.SerializeTicket();

                var existingToken = await _refreshTokenService.GetByClientIdAndUserNameAsync(token.ClientId, token.UserName);

                if (existingToken != null)
                {
                    await _refreshTokenService.DeleteAsync(existingToken.Id);
                }

                await _refreshTokenService.InsertAsync(token);

                context.SetToken(refreshTokenId);
            }
            catch (Exception ex)
            {
                _logger.Error(GetType(), ex, "RefreshTokenProvider/CreateAsync");
                throw ex;
            }
        }
        public bool CanInvokeBroker(CoreUIParent uiParent)
        {
            if (uiParent?.CallerViewController == null)
            {
                _logger.Error(iOSBrokerConstants.CallerViewControllerIsNullCannotInvokeBroker);
                throw new MsalClientException(MsalError.UIViewControllerRequiredForiOSBroker, MsalErrorMessage.UIViewControllerIsRequiredToInvokeiOSBroker);
            }

            var result = false;

            uiParent.CallerViewController.InvokeOnMainThread(() =>
            {
                result = UIApplication.SharedApplication.CanOpenUrl(new NSUrl(BrokerParameter.BrokerV2));
            });

            if (!result)
            {
                _logger.Info(result + iOSBrokerConstants.CanInvokeBrokerReturnsFalseMessage);
            }

            return(result);
        }
        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;
            }
        }
        internal static void SetBrokerResult(Intent data, int resultCode, ICoreLogger unreliableLogger)
        {
            try
            {
                if (data == null)
                {
                    unreliableLogger?.Info("Data is null, stopping. ");
                    return;
                }

                switch (resultCode)
                {
                case (int)BrokerResponseCode.ResponseReceived:
                    unreliableLogger?.Info("Response received, decoding... ");

                    s_androidBrokerTokenResponse =
                        MsalTokenResponse.CreateFromAndroidBrokerResponse(
                            data.GetStringExtra(BrokerConstants.BrokerResultV2),
                            s_correlationId);
                    break;

                case (int)BrokerResponseCode.UserCancelled:
                    unreliableLogger?.Info("Response received - user cancelled. ");

                    s_androidBrokerTokenResponse = new MsalTokenResponse
                    {
                        Error            = MsalError.AuthenticationCanceledError,
                        ErrorDescription = MsalErrorMessage.AuthenticationCanceled,
                    };
                    break;

                case (int)BrokerResponseCode.BrowserCodeError:
                    unreliableLogger?.Info("Response received - error. ");

                    dynamic errorResult      = JObject.Parse(data.GetStringExtra(BrokerConstants.BrokerResultV2));
                    string  error            = null;
                    string  errorDescription = null;

                    if (errorResult != null)
                    {
                        error            = errorResult[BrokerResponseConst.BrokerErrorCode]?.ToString();
                        errorDescription = errorResult[BrokerResponseConst.BrokerErrorMessage]?.ToString();

                        unreliableLogger?.Error($"error: {error} errorDescription {errorDescription}. ");
                    }
                    else
                    {
                        error            = BrokerConstants.BrokerUnknownErrorCode;
                        errorDescription = "Error Code received, but no error could be extracted. ";
                        unreliableLogger?.Error("Error response received, but not error could be extracted. ");
                    }

                    var httpResponse = new HttpResponse();
                    //TODO: figure out how to get status code properly deserialized from JObject
                    httpResponse.Body = errorResult[BrokerResponseConst.BrokerHttpBody]?.ToString();

                    s_androidBrokerTokenResponse = new MsalTokenResponse
                    {
                        Error            = error,
                        ErrorDescription = errorDescription,
                        SubError         = errorResult[BrokerResponseConst.BrokerSubError],
                        HttpResponse     = httpResponse,
                        CorrelationId    = s_correlationId
                    };
                    break;

                default:
                    unreliableLogger?.Error("Unknown broker response. ");
                    s_androidBrokerTokenResponse = new MsalTokenResponse
                    {
                        Error            = BrokerConstants.BrokerUnknownErrorCode,
                        ErrorDescription = "Broker result not returned from android broker. ",
                        CorrelationId    = s_correlationId
                    };
                    break;
                }
            }
            finally
            {
                s_readyForResponse.Release();
            }
        }
示例#28
0
        public MsalTokenResponse ParseSuccessfullWamResponse(
            WebTokenResponse webTokenResponse,
            out Dictionary <string, string> allProperties)
        {
            allProperties = new Dictionary <string, string>(8, StringComparer.OrdinalIgnoreCase);
            if (!webTokenResponse.Properties.TryGetValue("TokenExpiresOn", out string expiresOn))
            {
                _logger.Warning("Result from WAM does not have expiration. Marking access token as expired.");
                expiresOn = null;
            }

            if (!webTokenResponse.Properties.TryGetValue("ExtendedLifetimeToken", out string extendedExpiresOn))
            {
                extendedExpiresOn = null;
            }

            if (!webTokenResponse.Properties.TryGetValue("Authority", out string authority))
            {
                _logger.Error("Result from WAM does not have authority.");
                return(new MsalTokenResponse()
                {
                    Error = "no_authority_in_wam_response",
                    ErrorDescription = "No authority in WAM response"
                });
            }

            if (!webTokenResponse.Properties.TryGetValue("correlationId", out string correlationId))
            {
                _logger.Warning("No correlation ID in response");
                correlationId = null;
            }

            bool hasIdToken = webTokenResponse.Properties.TryGetValue("wamcompat_id_token", out string idToken);

            _logger.Info("Result from WAM has id token? " + hasIdToken);

            bool hasClientInfo = webTokenResponse.Properties.TryGetValue("wamcompat_client_info", out string clientInfo);

            _logger.Info("Result from WAM has client info? " + hasClientInfo);

            bool hasScopes = webTokenResponse.Properties.TryGetValue("wamcompat_scopes", out string scopes);

            _logger.InfoPii("Result from WAM scopes: " + scopes,
                            "Result from WAM has scopes? " + hasScopes);

            foreach (var kvp in webTokenResponse.Properties)
            {
                allProperties[kvp.Key] = kvp.Value;
            }

            MsalTokenResponse msalTokenResponse = new MsalTokenResponse()
            {
                AccessToken       = webTokenResponse.Token,
                IdToken           = idToken,
                CorrelationId     = correlationId,
                Scope             = scopes,
                ExpiresIn         = CoreHelpers.GetDurationFromWindowsTimestamp(expiresOn, _logger),
                ExtendedExpiresIn = CoreHelpers.GetDurationFromWindowsTimestamp(extendedExpiresOn, _logger),
                ClientInfo        = clientInfo,
                TokenType         = "Bearer",
                WamAccountId      = webTokenResponse?.WebAccount?.Id,
                TokenSource       = TokenSource.Broker
            };

            return(msalTokenResponse);
        }
        private async Task <HttpResponse> ExecuteWithRetryAsync(
            Uri endpoint,
            IDictionary <string, string> headers,
            HttpContent body,
            HttpMethod method,
            ICoreLogger logger,
            bool doNotThrow = false,
            bool retry      = true,
            CancellationToken cancellationToken = default)
        {
            Exception    timeoutException = null;
            bool         isRetryable      = false;
            bool         is5xxError       = false;
            HttpResponse response         = null;

            try
            {
                HttpContent clonedBody = body;
                if (body != null)
                {
                    // Since HttpContent would be disposed by underlying client.SendAsync(),
                    // we duplicate it so that we will have a copy in case we would need to retry
                    clonedBody = await CloneHttpContentAsync(body).ConfigureAwait(false);
                }

                response = await ExecuteAsync(endpoint, headers, clonedBody, method, cancellationToken).ConfigureAwait(false);

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    return(response);
                }

                logger.Info(string.Format(CultureInfo.InvariantCulture,
                                          MsalErrorMessage.HttpRequestUnsuccessful,
                                          (int)response.StatusCode, response.StatusCode));


                is5xxError  = (int)response.StatusCode >= 500 && (int)response.StatusCode < 600;
                isRetryable = is5xxError && !HasRetryAfterHeader(response);
            }
            catch (TaskCanceledException exception)
            {
                logger.Error("The HTTP request failed or it was canceled. " + exception.Message);
                isRetryable = true;

                if (cancellationToken.IsCancellationRequested)
                {
                    isRetryable = false;
                }

                timeoutException = exception;
            }

            if (isRetryable && retry)
            {
                logger.Info("Retrying one more time..");
                await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

                return(await ExecuteWithRetryAsync(
                           endpoint,
                           headers,
                           body,
                           method,
                           logger,
                           doNotThrow,
                           retry : false).ConfigureAwait(false));
            }

            logger.Warning("Request retry failed.");
            if (timeoutException != null)
            {
                throw new MsalServiceException(
                          MsalError.RequestTimeout,
                          "Request to the endpoint timed out.",
                          timeoutException);
            }

            if (doNotThrow)
            {
                return(response);
            }

            if (is5xxError)
            {
                throw MsalServiceExceptionFactory.FromHttpResponse(
                          MsalError.ServiceNotAvailable,
                          "Service is unavailable to process the request",
                          response);
            }

            return(response);
        }
        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);
        }