【问题标题】:Implement custom 401 handling for a WebBrowser control为 WebBrowser 控件实现自定义 401 处理
【发布时间】:2011-12-29 00:08:45
【问题描述】:

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

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

那么我可以做些什么来捕获 401 响应并以我自己的自定义方式处理它?

我认为我可以做一些事情,例如我可以捕获NavigateError 事件并以我自己的方式处理这些事情,但我没有看到任何东西。

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

【问题讨论】:

    标签: c# webbrowser-control http-status-code-401


    【解决方案1】:

    我发现为了能够在不丢失或删除授权标头的情况下浏览站点,我必须执行以下操作,否则对于再次提示用户的每个新页面。此解决方案也不需要启用 user: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());
        }
    

    【讨论】:

      【解决方案2】:

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

      我认为 WPF 网络浏览器没有针对其 IOleClientSite 实现的扩展点。您可以尝试托管一个 Winform webbrowser 类,该类具有一个重写的 CreateWebBrowserSiteBase 虚拟方法,该方法提供 IAuthenticate(Ex) 实现,或write a webbrowser wrapper from the ground up

      This may not work in a Citrix session.

      【讨论】:

      • 这正是我正在寻找的信息,谢谢!我现在已经为除第一个之外的所有身份验证请求进行了自定义处理。你知道我可能还缺少什么吗?
      • 你能把来自服务器的响应头添加到问题中吗?你可以在运行 IE 或 webbrowser 主机时使用 fiddler 收集响应。
      • 想通了! IE 中的已知错误,在解释一切的文章中有一个小参考。我在问题中添加了一些注释,以突出未来访问者的重要步骤。你知道,假设其他人在某个时候想做我必须做的同样疯狂的事情。 8)
      猜你喜欢
      • 1970-01-01
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      相关资源
      最近更新 更多