Как заблокировать загрузки в элементе управления .NET WebBrowser? - PullRequest
15 голосов
/ 27 января 2009

Мне нужно, чтобы элемент управления .NET WebBrowser не отображал сообщение "Хотите открыть или сохранить этот файл?" и «Сохранить как» диалоги. Вместо этого я хочу отобразить окно сообщения, сообщающее пользователям, что загрузка файлов отключена по соображениям безопасности.

Я начал с события FileDownload WebBrowser, но он не разрешает отмену. Затем я использовал подход из CodeProject: Extended .NET 2.0 WebBrowser Control , чтобы реализовать свое собственное событие на основе исходного COM-вызова с использованием интерфейса DWebBrowserEvents2. Когда я исправил код в соответствии с записью базы знаний MS об ошибке с сигнатурой FileDownload , был вызван обработчик событий, и я смог отменить загрузку.

Это не работает со всеми загрузками, хотя: URL-адреса загрузки, указывающие на URL, включая .exe, вызывают событие и могут быть отменены до появления диалогового окна - но для других (например, .do) обработчик события не вызывается до тех пор, пока пользователь не нажмет Open, Save или Cancel в диалоговом окне.

Возможное решение может заключаться в перехвате WH_CALLWNDPROCRET сообщений и «ответе» на диалог, прежде чем он будет показан пользователю , но это звучит как много усилий, и я также предпочел бы более чистое решение .. .

Кто-нибудь знает, как надежно заблокировать все загрузки?

Ответы [ 3 ]

3 голосов
/ 18 июня 2013

Единственный надежный способ - подключиться к очереди событий Windows и закрыть диалоговые окна (так как пользователь может получить доступ ко многим вещам). Вот что делает наш вспомогательный класс:

    void ListenForDialogCreation()
    {
        // Listen for name change changes across all processes/threads on current desktop...
        _WinEventHook = WinAPI.SetWinEventHook(WinAPI.EVENT_OBJECT_CREATE, procDelegate);
    }
    void StopListeningForDialogCreation()
    {
        WinAPI.UnhookWinEvent(_WinEventHook);
    }

    void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        const uint OBJID_WINDOW = 0;
        const uint CHILDID_SELF = 0;

        // filter out non-HWND, and things not children of the current application
        if (idObject != OBJID_WINDOW || idChild != CHILDID_SELF)
            return;

        //Get the window class name
        StringBuilder ClassName = new StringBuilder(100);
        WinAPI.GetClassName(hwnd, ClassName, ClassName.Capacity);

        // Send close message to any dialog
        if (ClassName.ToString() == "#32770")
        {
            WinAPI.SendMessage(hwnd, WinAPI.WM.CLOSE, IntPtr.Zero, IntPtr.Zero);
            if (OnDialogCancelled != null)
                OnDialogCancelled();
        }
        if (ClassName.ToString() == "#32768")
        {
            WinAPI.SendMessage(hwnd, WinAPI.WM.CLOSE, IntPtr.Zero, IntPtr.Zero);
            if (OnDialogCancelled != null)
                OnDialogCancelled();
        }

    }

    public delegate void OnDialogCancelledEvent();
    public event OnDialogCancelledEvent OnDialogCancelled;
  • # 32770 - класс диалога
  • # 32768 - всплывающее меню
  • пространство имен WinAPI - это наша оболочка для pinvoke.

Если вы не хотите блокировать все диалоги, вам нужно добавить некоторые дополнительные фильтры, как только вы поймете класс. Это зависит от того, насколько вы должны быть в безопасности. В $ WORK нам нужно было заблокировать все загрузки и выгрузки.

Необходимо отключить всплывающее меню, поскольку оно дает доступ к приложению справки, которое дает ссылки на веб-сайт Microsoft, что позволяет запускать полный экземпляр IE. Тогда они могут делать все, что хотят.

3 голосов
/ 28 января 2009

Вы можете использовать Navigating событие, которое позволяет отменить.

Внутри этого события вы можете попытаться подключиться к URL-адресу, по которому осуществляется навигация, проверить заголовки ответа http и отменить навигацию, если обнаружен неподходящий ContentType.

System.Net.WebRequest request = System.Net.WebRequest.Create(e.Url);

// we need only header part of http response
request.Method = "HEAD";

System.Net.WebResponse response = request.GetResponse();

// only text/html, text/xml, text/plain are allowed... extend as required
if (!response.ContentType.StartsWith("text/"))
{
  e.Cancel = true;
  MessageBox.Show("Not allowed for security resons...");
}

Очевидно, что это не пуленепробиваемое решение, но оно может дать вам представление о том, как начать работу (если вы не возражаете против дополнительной крошечной передачи туда и обратно только для получения заголовков ответа http).

Йенс Баннманн писал:

Это не идеально, так как я имею дело с веб-приложения, где дополнительные запрос может вызвать действие выполняется дважды: - (

Затем я создал бы простой прокси-сервер, который проверял бы все полученные данные и отфильтровывал бы все http-ответы, которые могли бы вызвать диалоговое окно «Сохранить как» в вашем элементе управления веб-браузера.

Проще говоря, не позволяйте вашему веб-браузеру напрямую подключаться к Интернету, но делегируйте все http-запросы на ваш специальный прокси-сервер, который отфильтрует все небезопасные ответы из Интернета.

0 голосов
/ 22 января 2012

Этот проект - http://www.codeproject.com/Articles/157329/Http-Monitor-for-Webbrowser-Control позволяет перехватывать и проверять HTTP-трафик из элемента управления WebBrowser.

Затем вы можете фильтровать данные по MIME и разрешать только HTML, изображения, скрипты и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...