// Test Windows Authentication
        private static bool ChallengeIWA(IdentityManager.CredentialRequestInfos credentialRequestInfos,
                                         Action <IdentityManager.Credential, Exception> callback)
        {
            if (credentialRequestInfos.AuthenticationType == IdentityManager.AuthenticationType.NetworkCredential &&
                credentialRequestInfos.ResponseHeaders != null && CredentialCache.DefaultCredentials != null)
            {
                // test that we didn't already try the IWA authentication
                if (TryDone(credentialRequestInfos.Url))
                {
                    return(false);
                }

                // get the WWW-Authenticate header
                string header = credentialRequestInfos.ResponseHeaders.Get("WWW-Authenticate");

                // if the header contains NTLM the server is using Integrated Windows
                // Authentication (IWA), so try the current user's credentials
                if (!string.IsNullOrEmpty(header) && header.Contains("NTLM"))                 // IWA
                {
                    var credential = new IdentityManager.Credential
                    {
                        Url         = credentialRequestInfos.Url,
                        Credentials = CredentialCache.DefaultCredentials
                    };
                    AddTry(credentialRequestInfos.Url);
                    callback(credential, null);
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Static challenge method leaveraging the SignInDialog in a child window.
        /// This method manages all credential types.
        /// Note however that in case of <see cref="IdentityManager.AuthenticationType.Certificate">certificate authentication</see> the SignInDialog UI is not used.
        /// The standard .Net dialog box for selecting an X.509 certificate from a certificate collection is used instead.
        /// </summary>
        /// <seealso cref="DoSignIn"/>
        /// <param name="credentialRequestInfos">The information about the credential to get.</param>
        /// <param name="callback">The callback.</param>
        /// <param name="generateTokenOptions">The generate token options.</param>
        public static void DoSignInEx(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions generateTokenOptions = null)
        {
            // Check if IWA authentication might be OK
            if (ChallengeIWA(credentialRequestInfos, callback))
            {
                return;
            }

            // Display UI for challenging
            System.Windows.Threading.Dispatcher d = null;
            if (Application.Current != null)
            {
                d = Application.Current.Dispatcher;
            }

            if (d != null && !d.CheckAccess())
            {
                //Ensure we are showing up the SignInDialog on the UI thread
                d.BeginInvoke((Action)(() => DoSignInInUIThreadEx(credentialRequestInfos, callback, generateTokenOptions)));
            }
            else
            {
                DoSignInInUIThreadEx(credentialRequestInfos, callback, generateTokenOptions);
            }
        }
        private static void ChallengeCertificate(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback)
        {
            var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            X509Certificate2Collection certificates;

            try
            {
                const string clientAuthOid = "1.3.6.1.5.5.7.3.2";                 // Client Authentication OID
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                // Find Client Authentication certificate
                certificates = store.Certificates.Find(X509FindType.FindByApplicationPolicy, clientAuthOid, true);                 // todo true);
            }
            catch (Exception)
            {
                certificates = null;
            }
            finally
            {
                store.Close();
            }

            if (certificates != null && certificates.Count >= 1)
            {
                // Let the user select/validate the certificate
                string url          = credentialRequestInfos.Url;
                string resourceName = GetResourceName(url);
                IdentityManager.ServerInfo serverInfo = IdentityManager.Current.FindServerInfo(url);
                string server = serverInfo == null?Regex.Match(url, "http.?//[^/]*").ToString() : serverInfo.ServerUrl;

                string message = string.Format(Properties.Resources.SignInDialog_CertificateRequired, resourceName, server);                 // certicate required to access {0} on {1}
                certificates = X509Certificate2UI.SelectFromCollection(certificates, null, message, X509SelectionFlag.SingleSelection);
            }

            IdentityManager.Credential credential = null;
            Exception error = null;

            if (certificates != null && certificates.Count > 0)
            {
                credential = new IdentityManager.Credential {
                    ClientCertificate = certificates[0]
                };
            }
            else
            {
                // Note : Error type is not that important since the error returned to the user is the initial HTTP error (Authorization Error)
                error = new System.Security.Authentication.AuthenticationException();
            }

            callback(credential, error);
        }
        private static void DoSignInInUIThreadEx(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions generateTokenOptions)
        {
            switch (credentialRequestInfos.AuthenticationType)
            {
            case IdentityManager.AuthenticationType.Token:
            case IdentityManager.AuthenticationType.NetworkCredential:
                DoSignInInUIThread(credentialRequestInfos.Url, callback, generateTokenOptions, credentialRequestInfos.AuthenticationType);
                break;

            case IdentityManager.AuthenticationType.Certificate:
                ChallengeCertificate(credentialRequestInfos, callback);
                break;
            }
        }