ThrottleTimer _updateDisplayNameTimer; // Updates the display name when the throttle interval expires
        public SignInStatusControl()
        {
            DefaultStyleKey = typeof(SignInStatusControl);
            DataContext = this;

            // Initialize the display name update timer.  Multiple credential change events may fire in 
            // rapid succession.  Throttling them makes it so that the display name update only fires once,
            // after all the change events are complete.
            _updateDisplayNameTimer = new ThrottleTimer(20, () => updateUserDisplayName());

            updateSignOutVisibility();
        }
        ThrottleTimer _updateDisplayNameTimer; // Updates the display name when the throttle interval expires
        public SignInStatusControl()
        {
            DefaultStyleKey = typeof(SignInStatusControl);
            DataContext     = this;

            // Initialize the display name update timer.  Multiple credential change events may fire in
            // rapid succession.  Throttling them makes it so that the display name update only fires once,
            // after all the change events are complete.
            _updateDisplayNameTimer = new ThrottleTimer(20, () => updateUserDisplayName());

            updateSignOutVisibility();
        }
        void rectangle_MouseLeave(object sender, MouseEventArgs e)
        {
            ThrottleTimer timer = new ThrottleTimer(200, delegate()
            {
                if (!_isMouseOverContextMenu)
                {
                    rangeContextMenuPopup.IsOpen = false;
                }
                timer = null;
            });

            timer.Invoke();
        }
예제 #4
0
        private IdentityManager.Credential cachedCredential; // Credential that was just retrieved from sign-in
        
        // Raised when an authentication challenge occurs in the application
        private async void OnChallenge(string url, Action<IdentityManager.Credential, Exception> callback,
            IdentityManager.GenerateTokenOptions options = null)
        {
            if (signedOut) // Sign-out occurred within the last two seconds.  Do not prompt for login.
            {
                callback(null, null);
                return;
            }

            var uri = new Uri(url);
            var tree = uri.AbsolutePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (tree[tree.Length - 2].ToLower() == "services" && tree[tree.Length - 3].ToLower() == "rest")
            {
                // Challenge is coming from a secure folder.  Do not prompt.
                callback(null, null);
                return;
            }

            // In some cases, multiple challenges are raised for resources at the same endpoint (e.g. tiles from 
            // hosted tile services in ArcGIS Online).  To keep the user from being prompted to login multiple times
            // in succession, each new credential is cached for a half-second.  If another challenge is raised
            // within a half second, and the domain of the current challenge matches that of the cached credential,
            // then the cached credential is used.

            // Initialize timer for clearing cached credential
            if (credentialCacheTimer == null)
            {
                credentialCacheTimer = new ThrottleTimer(2000, () => cachedCredential = null);
            }


            // If there is a credential cached, then sign-in has just occurred.  Check to see if the saved 
            // should also be used for this challenge
            if (cachedCredential != null)
            {
                try
                {
                    // check whether the domain of the currently requested URL matches that of the cached credential
                    if ((new Uri(url)).Domain().ToLower() == (new Uri(cachedCredential.Url).Domain().ToLower()))
                    {
                        // Domains match, so use the cached credential
                        callback(cachedCredential, null);
                        return;
                    }
                }
                catch { }
            }


            // Sometimes challenges are raised after sign-in is cancelled.  To avoid prompting the user after
            // cancellation, this timer will suppress challenges for two seconds.

            // Initialize timer for resetting sign-in cancellation tracking
            if (signInCancelledTimer == null)
            {
                signInCancelledTimer = new ThrottleTimer(2000, () =>
                {
                    // Two seconds has expired since sign-in was cancelled.  Reset tracking variables.
                    signInCancelled = false;
                    signInCancelUrl = null;
                });
            }

            // Check whether sign-in has been cancelled within two seconds
            if (signInCancelled && !string.IsNullOrEmpty(signInCancelUrl))
            {
                try
                {
                    // Check whether the domain of the requested URL matches that for the cancelled sign-in
                    Uri requestUri = new Uri(url);
                    Uri cancelUri = new Uri(signInCancelUrl);
                    if (requestUri.Domain().Equals(cancelUri.Domain(), StringComparison.OrdinalIgnoreCase)
                    && requestUri.AbsolutePath.Equals(cancelUri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
                    {
                        // Domains match - do not prompt user
                        callback(null, null);
                        return;
                    }
                }
                catch { }
            }

            var proxyUrl = options != null ? options.ProxyUrl : null;
            // Sign in suppression checks passed.  Try to authenticate using existing credentials
            // Try existing credentials
            IdentityManager.Credential cred = await ApplicationHelper.TryExistingCredentials(url, proxyUrl);
            if (cred != null)
            {
                // The existing credentials were sufficient for authentication.

                // If the request was for a URL in the current ArcGIS Portal, sign into Portal
                if (await url.IsFederatedWithPortal())
                    await ApplicationHelper.SignInToPortal(cred);

                // If there is not already a credential in the app's credentials collection that has the
                // same URL, add this one to the collection
                if (!UserManagement.Current.Credentials.Any(c => c.Url != null
                && c.Url.Equals(cred.Url, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(c.Token)))
                    UserManagement.Current.Credentials.Add(cred);

                // Pass the credential to the callback
                callback(cred, null);
                return;
            }

            // Try just getting a credential for the URL without specifying login info.  This can work if 
            // the browser has authenticated the user (e.g. using PKI or IWA auth)
            try
            {
                cred = await IdentityManager.Current.GenerateCredentialTaskAsyncEx(url, options);
            }
            catch { } // Swallow authorization exception

            if (cred != null)
            {
                callback(cred, null);
                return;
            }

            // Existing credentials were insufficient.  Prompt user to sign in.

            SignInCommand signInCommand = null;
            if (await url.IsFederatedWithPortal()) // Sign into ArcGIS portal
                signInCommand = new SignInToAGSOLCommand() { ProxyUrl = proxyUrl };
            else // Sign into ArcGIS Server
                signInCommand = new SignInToServerCommand() { Url = url, ProxyUrl = proxyUrl };

            signInCommand.SignedIn += (o, e) =>
            {
                // Temporarily store the credential and start the timer.  This allows this credential
                // to be re-used if there is another challenge with the same domain within a couple 
                // seconds of sign-in.
                cachedCredential = e.Credential;
                credentialCacheTimer.Invoke();

                // Pass the retrieved credential to the callback
                callback(e.Credential, null);
            };
            signInCommand.Cancelled += (o, e) =>
            {
                // Set the flags indicating that sign-in was cancelled and start the timer.  If another
                // challenge for the same resouce is raised within the next couple seconds, it is assumed
                // that the user should not be prompted because cancellation of sign-in has just occurred.
                signInCancelled = true;
                signInCancelUrl = url;
                signInCancelledTimer.Invoke();

                // Pass the retrieved credential to the callback
                callback(null, null);
            };

            // Promt user to sign-in
            signInCommand.Execute(null);
        }
예제 #5
0
 // Raised when the set of credentials retrieved for the application changes
 private void Credentials_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 {
     if (e.OldItems != null || (e.Action == NotifyCollectionChangedAction.Reset))
     {
         if (signedOutTimer == null)
             signedOutTimer = new ThrottleTimer(2000, () => signedOut = false);
         signedOut = true;
         signedOutTimer.Invoke();
     }
 }
 void rectangle_MouseLeave(object sender, MouseEventArgs e)
 {
     ThrottleTimer timer = new ThrottleTimer(200, delegate()
     {
         if (!_isMouseOverContextMenu)
         {
             rangeContextMenuPopup.IsOpen = false;
         }
         timer = null;
     });
     timer.Invoke();
 }