根据this article,我扩展了System.Windows.Forms.WebBrowser
类以实现自定义错误处理。大多数情况下,它都有效。
问题出现在浏览器收到“401 Unauthorized”响应时。这种响应导致WebBrowser
控件显示标准用户名/密码对话框。在取消该对话框之前,不会触发NavigateError
事件。
那么我该怎么做才能捕获401响应并以我自己的自定义方式处理它?
我认为我会做一些事情,例如我捕捉NavigateError
事件的事情,并以我自己的方式处理,但我没有看到任何东西。
编辑:找到解决方案!
重要的步骤是:
1. WebBrowser控件必须首先导航到非安全页面(“about:blank”是使用的典型URL),以避免KB 320153
2. WebBrowser控件的主机必须实现IOleClientSite
,IServiceProvider
和IAuthenticate
。
3. IServiceProvider.QueryService
必须使用IAuthenticate
实施处理IAuthenticate
服务请求,可以使用INET_E_DEFAULT_ACTION
响应处理所有其他服务请求。
4. IAuthenticate.Authenticate
是您的自定义身份验证处理程序。
答案 0 :(得分: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类,该类具有覆盖CreateWebBrowserSiteBase虚拟方法,该方法提供IAuthenticate(Ex)实现,或write a webbrowser wrapper from the ground up。
答案 1 :(得分:0)
我发现,为了能够在没有授权标题丢失或删除的情况下导航网站,我必须执行以下操作,否则每个新页面都会再次提示用户。此解决方案也不需要用户: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());
}