2011-11-14 35 views
1

根據this article,我擴展了System.Windows.Forms.WebBrowser類以實現自定義錯誤處理。大多數情況下,它的工作。爲WebBrowser控件實現自定義401處理

問題出現在瀏覽器得到「401未授權」響應時。這種響應會導致WebBrowser控件顯示標準的用戶名/密碼對話框。直到該對話框被取消,NavigateError事件纔會被觸發。

那麼,我能做些什麼來捕獲401響應,並以我自己的方式處理它?

我認爲會有一些我可以做的事情,例如我會捕獲NavigateError事件,並以我自己的方式處理這些事情,但我沒有看到任何事情。

編輯:解決方案找到了!
的重要步驟是:
1. web瀏覽器控件必須第一被導航到非安全頁面(「關於:空白」是所使用的典型的URL),以避免KB 320153
2,主機對於WebBrowser控件必須實現IOleClientSite,IServiceProviderIAuthenticate
3. IServiceProvider.QueryService必須處理IAuthenticate服務請求和IAuthenticate實現,所有其他服務請求可以使用INET_E_DEFAULT_ACTION響應處理。
4. IAuthenticate.Authenticate是您的自定義身份驗證處理程序。

回答

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)實現或write a webbrowser wrapper from the ground up的CreateWebBrowserSiteBase虛擬方法。

This may not work in a Citrix session

+0

這幾乎是我正在尋找的信息,謝謝!現在我已經爲除了第一個以外的所有身份驗證請求提供了自定義處理。你知道我可能會錯過的其他東西嗎? – Task

+0

您可以將服務器的響應標題添加到問題中嗎?您可以在運行IE或Web瀏覽器主機時使用fiddler收集響應。 –

+2

想通了!在IE中的已知錯誤,在文章中有一小段參考文獻解釋了一切。我在問題中添加了一些註釋以突出未來訪問者的重要步驟。你知道,假設其他人在某個時候想要做同樣瘋狂的事情,我必須做的。 8) – Task

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()); 
    }