2010-08-01 88 views
35

我正在使用webbrowser控件登錄任何站點。然後我想使用WebRequest(或WebClient)下載一些子頁面的HTML。這個鏈接必須要求認證。是否可以將身份驗證從Webbrowser轉移到WebRequest

如何將Web瀏覽器身份驗證信息傳輸到Webrequest或Webclient?

+0

上創建的cookie識別Web客戶端對象從類的名稱可以假設你問.NET基類庫類? – Oded 2010-08-01 15:13:40

+0

是的。 System.Net.WebRequest – ebattulga 2010-08-01 15:30:35

+0

鏈接需要什麼樣的身份驗證?登錄表單? SSL客戶端證書? Windows身份驗證? – 2010-08-05 06:28:21

回答

1

如果您可以在WebBrowser控件登錄到的站點設置後從WebBrowser控件中檢索必要的cookie,那麼您應該可以在WebRequest/WebClient中使用這些cookie。

This文章概述瞭如何在WebClient上使用cookie;你必須對它進行子類化,但它只是一個需要的覆蓋。

+0

我正在努力獲取cookie。但webbrowser.document.cookie爲null – ebattulga 2010-08-01 15:53:01

+0

@ebattulga - 如果cookie爲'HttpOnly',那麼您無法從javascript中檢索它。 http://msdn.microsoft.com/en-us/library/system.web.httpcookie.httponly.aspx – Giorgi 2010-08-05 11:36:14

0

要完成你想要做的事情並不容易。服務器可以使用客戶端(瀏覽器)的兩種身份驗證之一:

1)傳輸身份驗證 2)基於表單的身份驗證。

傳輸驗證:在這種情況下,驗證是使用傳輸連接本身完成的 - 在這裏它將使用自定義HTTP頭與多路握手進行驗證。

基於表單的身份驗證:這是在將憑證輸入表單時完成的傳統身份驗證。

在這兩種情況下,身份驗證可能在您的託管控件實例化時已經發生。正如有人建議你可以竊取該域的瀏覽器cookies,並將其與webclient一起使用,但它可能會或可能不會按照您的預期工作。

如果你想要做的只是下載一些東西,那麼我會看看是否可以使用瀏覽器工具,例如XmlHttpRequest或其他ajax機制來下載你想要的東西作爲所託管頁面的DOM的一部分控制。然後,您可以從您的控件中讀取該內容,或者也可以讓瀏覽器通過調用控件上的方法/屬性的方式將該內容注入到控件中。

[編輯]

找出(使用在Firefox插件螢火蟲)究竟是如何基於窗體身份驗證被在瀏覽器中完成。然後,您可以編寫代碼來完成與瀏覽器完全相同的請求/響應。對於網站來說,客戶端將像任何其他基於瀏覽器的客戶端一樣出現。那麼你應該可以從網站上下載任何你想要的東西。

希望這會有所幫助。

2

一種可能的方式做到這一點是使用InternetGetCookie函數獲取餅乾,構建相應的cookie對象,並使用它的CookieContainer

要檢索的HttpOnly餅乾使用InternetGetCookieEx

下面是一些例子:

InternetGetCookie() in .NET

Download using Internet Explorer Cookies

+0

這不是所有的cookies – ebattulga 2010-08-06 08:19:25

+0

嘗試InternetGetCookieEx與INTERNET_COOKIE_HTTPONLY或INTERNET_COOKIE_THIRD_PARTY – 2010-08-11 17:24:27

+1

INTERNET_COOKIE_HTTPONLY宣佈在哪裏? – 2013-06-08 17:19:10

0

我實際上在Windows Mobile平臺上經歷了同樣的問題,唯一有效的工作是在發送請求之前擴展WebBrowser控件(使用C++:<)來捕獲POST/GET變量。

這個庫可以幫助你:

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

「..the庫實現PassthroughAPP包由Igor Tandetnik,使客戶端攔截所有的HTTP和HTTPS請求和響應。」

因此,儘管無法在標準WebBrowser控件上獲得用於基本身份驗證的POST/GET變量,但如果使用擴展控件(例如鏈接的示例),實際上很多「擴展WebBrowser「控件是由於與您非常相似的問題而創建的。不幸的是,據我所知,你需要做到這一點使用非託管代碼/ C++ :(。

3

你應該能夠.Document.Cookie然後訪問WebBrowser控制的cookies在你的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) 

而且應該從你的WebBrowser控制權轉移的cookie來您HTTPWebRequest

+0

browser.Document.Cookie爲null – ebattulga 2010-08-12 04:53:59

+0

在讀取.Document.Cookie值之前,您是否已使用Web瀏覽器控件進行了連接和驗證? – Justin 2010-08-12 14:06:09

+0

WebBrowser.Document.Cookie不包含HttpOnly cookie。 – 2016-04-13 19:02:46

40

如果。問題只是「如何將Web瀏覽器身份驗證信息傳輸到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; 
} 
+0

請注意,默認情況下,這不會包含「安全」Cookie。爲了得到那些你只需要傳遞一個以https而不是http開頭的URI。 – AaronLS 2012-07-10 21:42:10

+2

對於HttpOnly標誌爲+1。 – Jaanus 2013-02-24 14:35:25

+0

其實,我沒有任何想法放置或使用此代碼,你能幫助嗎? – 2014-12-16 18:19:03

1

對於未來參考文獻而言,答案很晚。 WebBrowser使用UrlMon庫來管理每個進程的會話,因此可以使用UrlMon API(如URLOpenStreamURLDownloadToFile)來下載同一會話中的任何資源(API可以通過P/invoke從C#調用)。類似的問題回答了here

7

如果找到了這個解決方案。用下面的信息簡單地創建一個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)); 
+1

這是我唯一的woking解決方案。解析帶有重定向和SSO的頁面....非常感謝! – 2017-06-25 13:15:54

+0

太棒了!這也是我工作的唯一解決方案。保存了我的一週! – 2017-08-30 14:46:28

1

我知道這是很老的問題,但沒有答案標記,所以我想分享我準備

我還沒有轉移我的cookies,從網頁瀏覽器的解決方案webrequest,但我用webclient代替網絡請求,爲此,我遵循以下步驟

創建cookie識別的web客戶端從Web瀏覽器控件0解析餅乾 分配解析餅乾餅乾容器 使用的cookie容器 使用的cookie識別Web客戶端對象立即發送您的要求

詳細解釋了這個鏈接http://www.codewithasp.net/2016/06/transferring-cookies-webbrowser-webclient-c-net.html

相關問題