首页 文章

为WebBrowser控件实现自定义401处理

提问于
浏览
1

根据this article,我扩展了 System.Windows.Forms.WebBrowser 类以实现自定义错误处理 . 大多数情况下,它有效 .

当浏览器收到"401 Unauthorized"响应时,问题就出现了 . 这种响应导致 WebBrowser 控件显示标准用户名/密码对话框 . 在取消该对话框之前,不会触发 NavigateError 事件 .

那么我该怎么做才能捕获401响应并以我自己的自定义方式处理它?

我假设有一些我可以做的事情,比如我为捕获 NavigateError 事件所做的事情,并以我自己的方式处理,但我没有看到任何东西 .

Edit: Solution Found!
重要的步骤是:
1.首先必须将WebBrowser控件导航到非安全页面("about:blank"是使用的典型URL),以避免KB 320153
2. WebBrowser控件的主机必须实现 IOleClientSiteIServiceProviderIAuthenticate .
3. IServiceProvider.QueryService 必须使用 IAuthenticate 实现处理 IAuthenticate 服务请求,所有其他服务请求都可以使用 INET_E_DEFAULT_ACTION 响应进行处理 .
4. IAuthenticate.Authenticate 是您的自定义身份验证处理程序 .

2 回答

  • 3

    implement IAuthenticate and IAuthenticateEx on your webbrowser host . 基本上,您的IOleClientSite实现需要响应IServiceProvider.QueryService,并在服务为IID_IAuthenticate时返回IAuthenticate(Ex)接口(不是托管的接口,从Marshal.GetComInterfaceForObject返回的本机接口) . 对于无法识别的服务请求,QueryService应返回INET_E_DEFAULT_ACTION .

    我不认为WPF webbrowser的IOleClientSite实现有扩展点 . 您可以尝试托管Winform webbrowser类,该类具有提供IAuthenticate(Ex)实现的覆盖CreateWebBrowserSiteBase虚拟方法,或write a webbrowser wrapper from the ground up .

    This may not work in a Citrix session .

  • 0

    我发现,为了能够在没有授权 Headers 丢失或删除的情况下导航网站,我必须执行以下操作,否则每个新页面都会再次提示用户 . 此解决方案也不需要用户:password @ site语法启用 .

    private bool _redirected = false;
        private const string BaseUrl = @"http://mySite";
    
        private void Navigate()
        {
            var helpUrl = BaseUrl;
            var authHeader = GetAuthHeader();
    
            _docWindow.Browser.Navigate(helpUrl, string.Empty, null, authHeader);           
            _docWindow.Browser.Navigating += Browser_Navigating;
    
        }
    
        private string GetAuthHeader()
        {
            byte[] authData = UnicodeEncoding.UTF8.GetBytes(_userName + ":" + _password);
            string authHeader = "Authorization: Basic " + Convert.ToBase64String(authData);
            return authHeader;
        }
    
        void Browser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        {            
            if (_redirected)
            {
                _redirected = false;
                return;
            }
            var newPage = BaseUrl + e.Uri.AbsolutePath;
    
            e.Cancel = true;
            _redirected = true;
            _docWindow.Browser.Navigate(newPage, string.Empty, null, GetAuthHeader());
        }
    

相关问题