WebBrowser.Document property getter throws UnauthorizedAccessException
Asked Answered
H

1

0

We have a Windows Forms app that hosts a web application from http://localhost (on a port selected at runtime) in a WebBrowser control which mostly works fine. Within the webapp there is a 'help' link that pops up a new window, and we handle this by listening to the NewWindow event and showing the help URL in another WebBrowser control within another Form/Window, this also mostly works fine.

The problem is that the html help files are generating script errors which cause annoying popup error messages. When viewed from within a browser (confirmed with IE, Chrome and Firefox) the dev tools show the script errors occurring but the browsers suppress them by default (no annoying pop-up). So to suppress the errors when using the WebBrowser control we followed an approach from 'Disable JavaScript error in WebBrowser control'

Side note: The top answer approach of using webBrowser.ScriptErrorsSuppressed = true; actually suppresses all pop-ups which we'd prefer not to do, so we went with the second answer approach of attaching an error event handler:

    void FooWebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
    {
        SuppressErrorDialogs(sender);
    }

    void FooWebBrowser_FileDownload(object sender, EventArgs e)
    {
        SuppressErrorDialogs(sender);
    }

    private void SuppressErrorDialogs(object sender)
    {
        WebBrowser webBrowser = sender as WebBrowser;
        if(null == webBrowser) {
            return;
        }

        HtmlDocument document = webBrowser.Document;
        if(null == document) {
            return;
        }

        HtmlWindow window = document.Window;
        if(null == window) {
            return;
        }

        window.Error += (o, args) => args.Handled = true;
    }

The .Document property getter in SuppressErrorDialogs fails as follows:

System.UnauthorizedAccessException was unhandled by user code
  Message=Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.UnsafeNativeMethods.IHTMLLocation.GetHref()
       at System.Windows.Forms.WebBrowser.get_Document()
       at FSG.Process.Offline.FocusWebBrowser.SuppressErrorDialogs(Object sender) in C:\CoreFocus360\Technology\Process\Main\Assemblies\FSG.Process.Offline\FocusWebBrowser.cs:line 55
       at FSG.Process.Offline.FocusWebBrowser.FocusWebBrowser_Navigated(Object sender, WebBrowserNavigatedEventArgs e) in C:\CoreFocus360\Technology\Process\Main\Assemblies\FSG.Process.Offline\FocusWebBrowser.cs:line 40
       at System.Windows.Forms.WebBrowser.OnNavigated(WebBrowserNavigatedEventArgs e)
       at System.Windows.Forms.WebBrowser.WebBrowserEvent.NavigateComplete2(Object pDisp, Object& urlObject)
  InnerException: 

So the error has been raised from within IHTMLLocation.GetHref(). We spent some time investigating the WebPermission(s) in force at the time of the call before realising that this error has not been thrown by .Net's own security model - it originates from the underlying IE browser control.

All URLs in our webapp (including the help files) are located on localhost, so this error is really not expected, i.e. we don't expect cross site scripting attack protection to be triggered.

==== UPDATE ====

This is apparently caused by cross frame scripting security. I was unable to overcome this issue with the code posted up top, but there was an alternative solution to the original problem (suppress script errors), see Override IOleCommandTarget to suppress script errors

Haig answered 7/6, 2013 at 23:33 Comment(1)
If cross frame scripting is not enabled (disabled by default), this exception is expected when the page contains frames that you won't have access to.Trinia
S
1

If you only want to suppress script errors, handle OLECMDID_SHOWSCRIPTERROR from the CGID_DocHostCommandHandler command group in your host's IOleCommandTarget implementation. To handle this in Windows Forms's WebBrowser class, you need your own WebBrowserSite class that implements IOleCommandTarget and use it as your webbrowser's control site. If you host the ActiveX version of IE directly, check https://code.google.com/p/csexwb2/

Note implementing IOleCommandTarget will have the webbrowser control routing all kinds of commands (e.g. OLECMDID_PRINT, OLECMDID_SHOWPAGEACTIONMENU, OLECMDID_PASTESPECIAL,OLECMDID_SETPROGRESSPOS, etc) to the host. If you are not interested in changing the default behavior for those commands, remember to return OLECMDERR_E_NOTSUPPORTED (if you handle the group but not the command) or OLECMDERR_E_UNKNOWNGROUP, otherwise your application may crash.

Statant answered 10/6, 2013 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.