1

我正在尝试从 Web 应用程序中的 WebBrowser 控件访问 HTTPS 站点,以从该站点获取一些基本信息(该站点此时没有 Web 服务或任何其他 API)当我从 IIS Express 执行此操作时我能够连接登录并导航到其他页面,就像从该系统上的网络浏览器直接连接时一样,一切正常。

从大多数开发系统,即 Windows 10 或 Windows Server 2016,我可以发布 Web 应用程序,连接到 Web 应用程序,然后通过 Web 应用程序连接到站点,登录和加载其他页面一切正常。但…。当我部署到 GoDaddy 并通过应用程序连接到站点时,我能够成功登录,但是当我导航到另一个页面时,我被重定向到登录页面。

我注意到,在通过 GoDaddy 上的应用程序时,我没有取回任何 JSESSION Cookie,但在所有其他成功案例中我确实得到了它们。我在登录目标站点之前收到了 JESSSON Cookie:http ://www.altavista.com/但任何在连接时返回 cookie 的网站就足够了。我已将用户代理更改为我在桌面上使用并连接的同一代理,但在 GoDaddy 上仍然获得相同的结果。

我已经在受 SSL 保护 (HTTPS) 和不只是 (HTTP) 的 GoDaddy 站点上尝试过此操作。希望有人在使用 WebBrowser 控件之前遇到过此类问题?

这是代码的测试片段(您可能会注意到,我已经尝试了很多方法来解决 CookiePresistance、清除 Cookie、JScript 以清除状态等:

public static class NativeMethods
{
    [DllImport("wininet.dll", SetLastError = true)]
    private static extern bool InternetSetOption(IntPtr hInternet, int dwOption,
                                                 IntPtr lpBuffer, int lpdwBufferLength);

    public static void SuppressCookiePersist()
    {
        int dwOption = 81; //INTERNET_OPTION_SUPPRESS_BEHAVIOR
        int option = 3; // INTERNET_SUPPRESS_COOKIE_PERSIST

        IntPtr optionPtr = Marshal.AllocHGlobal(sizeof(int));
        Marshal.WriteInt32(optionPtr, option);

        bool x = InternetSetOption(IntPtr.Zero, dwOption, optionPtr, sizeof(int));
        Marshal.FreeHGlobal(optionPtr);
    }
    public static void EnableCookiePersist()
    {
        int dwOption = 81; //INTERNET_OPTION_SUPPRESS_BEHAVIOR
        int option = 4; // INTERNET_SUPPRESS_COOKIE_POLICY ignores policy and allows cookies to be set https://msdn.microsoft.com/en-us/library/windows/desktop/aa385328(v=vs.85).aspx

        IntPtr optionPtr = Marshal.AllocHGlobal(sizeof(int));
        Marshal.WriteInt32(optionPtr, option);

        InternetSetOption(IntPtr.Zero, dwOption, optionPtr, sizeof(int));
        option = 1;
        Marshal.WriteInt32(optionPtr, option);
        InternetSetOption(IntPtr.Zero, dwOption, optionPtr, sizeof(int));
        Marshal.FreeHGlobal(optionPtr);
    }
    public static void ClearBrowserSession()
    {
        int dwOption = 42; //INTERNET_OPTION_END_BROWSER_SESSION

        InternetSetOption(IntPtr.Zero, dwOption, IntPtr.Zero, 0);

    }
}   

public partial class TestStub: System.Web.UI.Page
{
    protected void btnNavigate_Click(object sender, EventArgs e)
    {
        NativeMethods.EnableCookiePersist();
        if(tbUrl.Text == "")
        {
            Client_Alert("Please enter url");
            return;
        }
        if (tbUserAgent.Text == "")
            tbUserAgent.Text = CurrentUserAgent;
        object o = tbUrl.Text;

        var t = new Thread((ParameterizedThreadStart)GetPage);
        t.SetApartmentState(ApartmentState.STA);
        t.Start(o);

        GettingPage = true;
        while (GettingPage == true)
            Thread.Sleep(500);
        t.Join();
        return;
    }

    private void GetPage(object o)
    {

        StringBuilder SB = new StringBuilder();
        DirectorBrowser = new WebBrowser();

        NativeMethods.ClearBrowserSession();
        DirectorBrowser.ScrollBarsEnabled = false;
        DirectorBrowser.ScriptErrorsSuppressed = true;
        DirectorBrowser.AllowNavigation = true;
        DirectorBrowser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; '); for (e = 0; e < a.length && a[e]; e++) { f++; for (b = '.' + location.host; b; b = b.replace(/^ (?:% 5C.|[^% 5C.] +) /, '')){ for (c = location.pathname; c; c = c.replace(/.$/, '')) { document.cookie = (a[e] + '; domain=' + b + '; path=' + c + '; expires=' + new Date((new Date()).getTime() - 1e11).toGMTString()); } }}})())");
        NativeMethods.EnableCookiePersist();

        DirectorBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_NoticeCompleted);
        Uri url = new Uri((string)o);
        DirectorBrowser.Navigate(url, null, null, "User-Agent: " + tbUserAgent.Text);

        GettingPage = true;

        while (GettingPage == true)
        {
            System.Windows.Forms.Application.DoEvents();
            Thread.Sleep(500);
        }
    }
    private void browser_NoticeCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (GettingPage == true)
        {
            HtmlElement body = DirectorBrowser.Document.Body;
            HtmlElementCollection inputs = DirectorBrowser.Document.GetElementsByTagName("INPUT");
            HtmlElementCollection forms = DirectorBrowser.Document.Forms;
            body = DirectorBrowser.Document.Body;
            string webResults = body.InnerHtml;
            HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
            htmlDoc.LoadHtml(webResults);
            htmlDoc.OptionFixNestedTags = true;

            tbMaintenanceResults.Text = "Cookies: <br>" + DirectorBrowser.Document.Cookie + "<br>" + body.InnerHtml;
            GettingPage = false;
        }
        else
        {
            GettingPage = false;
        }
    }
}
4

1 回答 1

0

添加自定义安全管理器后,仍然没有成功:

public partial  class InternetSecurityManager : IInternetSecurityManager
{
    private static Guid _CLSID_SecurityManager = new Guid("7b8a2d94-0ac9-11d1-896c-00c04fb6bfc4");
    private static string[] ZoneNames = new[] { "Local", "Intranet", "Trusted", "Internet", "Restricted" };public static string GetUrlZone(string url)
    { 
        Type t = System.Type.GetTypeFromCLSID(_CLSID_SecurityManager);
        IInternetSecurityManager securityManager = (IInternetSecurityManager)System.Activator.CreateInstance(t);
        try
        {
            uint zone = 0;
            int hResult = securityManager.MapUrlToZone(url, ref zone, 0);
            if (hResult != 0)
                throw new COMException("Error calling MapUrlToZone, HRESULT = " + hResult.ToString("x"), hResult);

            if (zone < ZoneNames.Length)
                return ZoneNames[zone];
            return "Unknown - " + zone;
        }
        finally
        {
            Marshal.ReleaseComObject(securityManager);
        }
    }
    public static void GetUrlZoneCookiesPermissions(string url)
    {
        Type t = System.Type.GetTypeFromCLSID(_CLSID_SecurityManager);
        IInternetSecurityManager securityManager = (IInternetSecurityManager)System.Activator.CreateInstance(t);
        try
        { 
            uint puaf = 0x00000040;  //PUAF TRUSTED
            byte obptr = 0;
            int hResult = securityManager.ProcessUrlAction(url, 0x00001A06, out obptr, 1, 0, 0, puaf, 0);
            //hResult = securityManager.ProcessUrlAction(url, 0x00001A10, out obptr, 1, 0, 0, puaf, 0);
            hResult = securityManager.ProcessUrlAction(url, 0x00001A03, out obptr, 1, 0, 0, puaf, 0);
            return;
        }
        finally
        {
            Marshal.ReleaseComObject(securityManager);
        }
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int SetSecuritySite([In] IntPtr pSite)
    {
        return Convert.ToInt32( 0x800C0011); //INET_E_DEFAULT_ACTION;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int GetSecuritySite([Out] IntPtr pSite)
    {
        return Convert.ToInt32(0x800C0011); //INET_E_DEFAULT_ACTION;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref uint pdwZone, uint dwFlags)
    {
        return Convert.ToInt32(0x800C0011); //INET_E_DEFAULT_ACTION;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int GetSecurityId([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved)
    {
        return Convert.ToInt32(0x800C0011); //INET_E_DEFAULT_ACTION;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, uint dwAction, out byte pPolicy, uint cbPolicy, byte pContext, uint cbContext, uint dwFlags, uint dwReserved)
    {

                pPolicy = 0;
                return 0;// S_OK;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref Guid guidKey, ref byte ppPolicy, ref uint pcbPolicy, ref byte pContext, uint cbContext, uint dwReserved)
    {
        return Convert.ToInt32(0x800C0011); //INET_E_DEFAULT_ACTION;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int SetZoneMapping(uint dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, uint dwFlags)
    {
        return Convert.ToInt32(0x800C0011); //INET_E_DEFAULT_ACTION;
    }

    [return: MarshalAs(UnmanagedType.I4)]
    public int GetZoneMappings(uint dwZone, out UCOMIEnumString ppenumString, uint dwFlags)
    {
        ppenumString = null;
        return Convert.ToInt32(0x800C0011); //INET_E_DEFAULT_ACTION;
    }


}

[ComImport, GuidAttribute("79EAC9EE-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInternetSecurityManager
{
    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int SetSecuritySite([In] IntPtr pSite);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetSecuritySite([Out] IntPtr pSite);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl,
             ref UInt32 pdwZone, UInt32 dwFlags);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetSecurityId([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl,
              [MarshalAs(UnmanagedType.LPArray)] byte[] pbSecurityId,
              ref UInt32 pcbSecurityId, uint dwReserved);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl,
             UInt32 dwAction, out byte pPolicy, UInt32 cbPolicy,
             byte pContext, UInt32 cbContext, UInt32 dwFlags,
             UInt32 dwReserved);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl,
              ref Guid guidKey, ref byte ppPolicy, ref UInt32 pcbPolicy,
              ref byte pContext, UInt32 cbContext, UInt32 dwReserved);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int SetZoneMapping(UInt32 dwZone,
               [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern,
               UInt32 dwFlags);

    [return: MarshalAs(UnmanagedType.I4)]
    [PreserveSig]
    int GetZoneMappings(UInt32 dwZone, out UCOMIEnumString ppenumString,
            UInt32 dwFlags);


    }
}

我从 2006 年发现了这篇文章:http ://www.tech-archive.net/Archive/InetSDK/microsoft.public.inetsdk.programming.webbrowser_ctl/2006-03/msg00073.html 显然 Cookie 不是由他们的安全管理器处理的由无法自定义的区域管理器处理。解决此问题的唯一方法是为您的特定需求添加一个附加区域到注册表。不幸的是,当您使用 WebBrowser 控件时,无法通过代码执行此操作。如果您的站点托管在 Web Farm 中,则您无权访问注册表,因此将需要另一种方法(可能是 IE 插件或部署在您有权访问并有权将默认浏览器设置为您的浏览器的服务器上)需要)

于 2017-08-16T14:31:57.887 回答