Подтвердить что ты не робот

Возможно ли передать аутентификацию из Webbrowser в WebRequest

Я использую элемент управления webbrowser для входа на любой сайт. А затем я хочу загрузить некоторые подстраницы html с помощью WebRequest (или WebClient). Для этих ссылок требуется аутентификация.

Как передать данные аутентификации Webbrowser в Webrequest или Webclient?

4b9b3361

Ответ 1

Если вопрос заключается только в том, "Как передать информацию аутентификации Webbrowser в Webrequest или Webclient?" этого кода достаточно:

Вы можете вызвать метод GetUriCookieContainer, который возвращает вам CookieContainer, который можно использовать для последующего вызова с помощью объекта WebRequest.

  [DllImport("wininet.dll", SetLastError = true)]
    public static extern bool InternetGetCookieEx(
        string url, 
        string cookieName, 
        StringBuilder cookieData, 
        ref int size,
        Int32  dwFlags,
        IntPtr  lpReserved);

    private const Int32 InternetCookieHttponly = 0x2000;

/// <summary>
/// Gets the URI cookie container.
/// </summary>
/// <param name="uri">The URI.</param>
/// <returns></returns>
public static CookieContainer GetUriCookieContainer(Uri uri)
{
    CookieContainer cookies = null;
    // Determine the size of the cookie
    int datasize = 8192 * 16;
    StringBuilder cookieData = new StringBuilder(datasize);
    if (!InternetGetCookieEx(uri.ToString(), null, cookieData, ref datasize, InternetCookieHttponly, IntPtr.Zero))
    {
        if (datasize < 0)
            return null;
        // Allocate stringbuilder large enough to hold the cookie
        cookieData = new StringBuilder(datasize);
        if (!InternetGetCookieEx(
            uri.ToString(),
            null, cookieData, 
            ref datasize, 
            InternetCookieHttponly, 
            IntPtr.Zero))
            return null;
    }
    if (cookieData.Length > 0)
    {
        cookies = new CookieContainer();
        cookies.SetCookies(uri, cookieData.ToString().Replace(';', ','));
    }
    return cookies;
}

Ответ 2

Если это решение найдено. Просто создайте файл Class.cs с приведенной ниже информацией и вызовите статическую функцию GetCookieInternal.

using System;
using System.ComponentModel;
using System.Net;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Windows.Forms;


internal sealed class NativeMethods
{
    #region enums

    public enum ErrorFlags
    {
        ERROR_INSUFFICIENT_BUFFER = 122,
        ERROR_INVALID_PARAMETER = 87,
        ERROR_NO_MORE_ITEMS = 259
    }

    public enum InternetFlags
    {
        INTERNET_COOKIE_HTTPONLY = 8192, //Requires IE 8 or higher   
        INTERNET_COOKIE_THIRD_PARTY = 131072,
        INTERNET_FLAG_RESTRICTED_ZONE = 16
    }

    #endregion

    #region DLL Imports

    [SuppressUnmanagedCodeSecurity, SecurityCritical, DllImport("wininet.dll", EntryPoint = "InternetGetCookieExW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
    internal static extern bool InternetGetCookieEx([In] string Url, [In] string cookieName, [Out] StringBuilder cookieData, [In, Out] ref uint pchCookieData, uint flags, IntPtr reserved);

    #endregion
}


/// <SUMMARY></SUMMARY>   
/// WebBrowserCookie?   
/// webBrowser1.Document.CookieHttpOnlyCookie   
///    
public class FullWebBrowserCookie : WebBrowser
{

    [SecurityCritical]
    public static string GetCookieInternal(Uri uri, bool throwIfNoCookie)
    {
        uint pchCookieData = 0;
        string url = UriToString(uri);
        uint flag = (uint)NativeMethods.InternetFlags.INTERNET_COOKIE_HTTPONLY;

        //Gets the size of the string builder   
        if (NativeMethods.InternetGetCookieEx(url, null, null, ref pchCookieData, flag, IntPtr.Zero))
        {
            pchCookieData++;
            StringBuilder cookieData = new StringBuilder((int)pchCookieData);

            //Read the cookie   
            if (NativeMethods.InternetGetCookieEx(url, null, cookieData, ref pchCookieData, flag, IntPtr.Zero))
            {
                DemandWebPermission(uri);
                return cookieData.ToString();
            }
        }

        int lastErrorCode = Marshal.GetLastWin32Error();

        if (throwIfNoCookie || (lastErrorCode != (int)NativeMethods.ErrorFlags.ERROR_NO_MORE_ITEMS))
        {
            throw new Win32Exception(lastErrorCode);
        }

        return null;
    }

    private static void DemandWebPermission(Uri uri)
    {
        string uriString = UriToString(uri);

        if (uri.IsFile)
        {
            string localPath = uri.LocalPath;
            new FileIOPermission(FileIOPermissionAccess.Read, localPath).Demand();
        }
        else
        {
            new WebPermission(NetworkAccess.Connect, uriString).Demand();
        }
    }

    private static string UriToString(Uri uri)
    {
        if (uri == null)
        {
            throw new ArgumentNullException("uri");
        }

        UriComponents components = (uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString);
        return new StringBuilder(uri.GetComponents(components, UriFormat.SafeUnescaped), 2083).ToString();
    }
}   

Пример:

var cookies = FullWebBrowserCookie.GetCookieInternal(webBrowser1.Url, false);
WebClient wc = new WebClient();
wc.Headers.Add("Cookie: " + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
byte[] result = wc.UploadData("<URL>", "POST", System.Text.Encoding.UTF8.GetBytes(postData));

Ответ 3

Вы должны иметь доступ к файлам cookie элемента управления WebBrowser с помощью .Document.Cookie, а затем в HTTPWebRequest вы можете добавить этот файл cookie в свой контейнер cookie.
Вот пример (VB.NET, потому что я больше всего там знаком):

Dim browser As New WebBrowser()
/*Do stuff here to auth with your webbrowser and get a cookie.*/

Dim myURL As String = "http://theUrlIWant.com/"
Dim request As New HTTPWebRequest(myURL)
request.CookieContainer = New CookieContainer()
request.CookieContainer.SetCookies(myURL, browser.Document.Cookie)

И это должно передать файл cookie из вашего элемента управления WebBrowser в ваш класс HTTPWebRequest.

Ответ 4

Один из возможных способов сделать это - получить файл cookie с помощью функции InternetGetCookie, построить соответствующий объект cookie и использовать его для CookieContainer

Чтобы извлечь файлы cookie HttpOnly, используйте InternetGetCookieEx

Вот несколько примеров:

InternetGetCookie() в .NET

Загрузка с использованием файлов cookie Internet Explorer

Ответ 5

Если вы можете получить необходимые файлы cookie из элемента управления WebBrowser после того, как они установлены на сайте, в который вы входите, вы сможете использовать те же файлы cookie с WebRequest/WebClient.

В этой статье описывается, как использовать файлы cookie с WebClient; вы должны подклассифицировать его, но это нужно только одному переопределению.

Ответ 6

Поздний ответ для будущих ссылок. WebBrowser использует библиотека UrlMon, которая управляет сеансом для каждого процесса, поэтому API-интерфейсы UrlMon, такие как URLOpenStream или URLDownloadToFile можно использовать для загрузки любого ресурса в тот же сеанс (API можно вызывать из С# через P/invoke). Аналогичный вопрос ответил здесь.

Ответ 7

Я знаю, что это очень старый вопрос, но есть ответ, отмеченный так, что я хочу поделиться решением, которое я приготовил

Я не передал свои файлы cookie из webbrowser в webrequest, но я использовал webclient вместо webrequest, и для этого есть следующие шаги, которые я выполнил

Создать веб-клиент с поддержкой cookie Выбирать файлы cookie из веб-браузера Назначить обработанные файлы cookie в контейнер cookie Создавать веб-клиент с поддержкой cookie с помощью контейнера cookie Использовать веб-клиент с поддержкой cookie для отправки ваших запросов сейчас

Подробное описание этой ссылки http://www.codewithasp.net/2016/06/transferring-cookies-webbrowser-webclient-c-net.html

Ответ 8

Нелегко выполнить то, что вы пытаетесь сделать. Сервер может использовать один из двух типов аутентификации с клиентом (браузером)

1) Транспортная аутентификация 2) Аутентификация на основе форм.

Transport auth: в этом случае аутентификация выполняется с использованием самого транспортного соединения - здесь он будет использовать пользовательские заголовки HTTP с многопользовательским рукопожатием для выполнения авторизации.

Основанный на формах auth: это традиционное auth, которое выполняется при вводе ваших учетных данных в форму.

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

Если все, что вы хотите сделать, это загрузить что-то, я бы посмотрел, могу ли я использовать возможности браузеров, например, XmlHttpRequest или какой-либо другой механизм ajax для загрузки того, что вы хотите как часть DOM страницы, на которой размещается контроль. Затем вы можете прочитать это содержимое из своего элемента управления, или вы также можете заставить браузер вводить этот контент в свой контроль с помощью Javascript, вызывающего метод/свойство вашего элемента управления.

[EDIT]

Узнайте (используя плагин Firebug в firefox) точно, как выполняется создание auth в браузере. Затем вы можете написать код, чтобы сделать тот же запрос/ответ, который делает браузер. На веб-сайт клиент появится как любой другой клиент на базе браузера. Затем вы сможете загрузить все, что захотите, с веб-сайта.

Надеюсь, что это поможет.

Ответ 9

Я действительно пережил эту же проблему на платформе Windows Mobile, и единственное, что работало, это расширить элемент управления WebBrowser (используя С++: <) для захвата валов POST/GET до отправки запроса.

Эта библиотека может помочь вам:

http://www.codeproject.com/KB/miscctrl/csEXWB.aspx

". Библиотека реализует пакет PassthroughAPP от Игоря Тандетника, который позволяет клиенту перехватывать все запросы и ответы HTTP и HTTPS.

Таким образом, хотя невозможно получить POST/GET-вары, используемые для вашего основного auth на стандартном элементе управления WebBrowser, было бы возможно, если вы используете расширенный элемент управления, такой как связанный с ним образец, - на самом деле многие "Extended WebBrowser" "элементы управления созданы из-за проблем, очень похожих на ваши. К сожалению, насколько я знаю, вам нужно сделать это с помощью неуправляемого кода/С++: (.