WPF WebBrowser控件中的持久性cookie?

时间:2010-11-25 15:56:38

标签: wpf cookies wpf-controls browser

我正在使用WPF WebBrowser在应用程序内显示在线帮助(只是几个小网页)。其中一些页面使用cookie仅在页面被查看的前几次显示项目(这是“为什么不尝试X”类型的东西)。

但是,出于某种原因,cookie似乎不在WebBrowser控件中工作。它们在完整的IE以及Firefox和Chrome中运行良好(因此项目正确隐藏),但是当通过WPF WebBrowser控件查看时它们永远不会隐藏。

在WPF WebBrowser控件中使用cookie有什么特别之处吗?似乎所有cookie都只存储在内存中,而不是存储在磁盘上。

以下是浏览器中的其中一个页面(Cookie工作的地方):

Help pane inside a browser

以下是应用内部完全相同的页面:

Help pane inside the application

只有在使用该软件的前几次才能看到其他内容(即它应该在该网页的N次视图后隐藏),但由于我无法获得cookie,因此它始终可见。

2 个答案:

答案 0 :(得分:6)

Internet Explorer(或托管版本)中的Cookie处理与IE自身的“URL安全区域”概念相关联,doc:About URL security Zones

因此,IE使用应用于网址的各种算法来确定网址区域。根据区域的不同,托管浏览器可能支持也可能不支持会话或持久性cookie。

奇怪的是,当我创建一个小的WPF示例时,将Web浏览器添加到它并导航到这个持久性cookie测试器utiliy页面:http://www.rbaworld.com/Security/Computers/Cookies/givecook.shtml,它工作正常。每次我启动示例应用程序时,计数器都会增加,所以不是每个人都可以重现您的问题。嗯,这就是URL安全区域的全部目的:它可能因机器,用户,Windows策略等而异......

接下来的问题是:我可以更改您正在运行的区域吗?简短而简单的答案是......不,因为它与安全密切相关。

如果您自己托管IE,则可以按照此处所述实现自己的安全区域句柄:Implementing a Custom Security Manager并在此处示例:SAMPLE: Secumgr.exe Overrides Security Manager for WebBrowser Host但您依赖WPF的webbrowser,不允许任何覆盖...您可以访问Reflector并复制所有WPF私有/内部代码,但这是一个有风险的工作日志!

您可以尝试的最后一件事是操纵标准的Internet Security Manager。下面是一些提供一些提示的示例代码。至少你应该能够确定你正在运行的区域(MapUrltoZone)并更改cookie(TryAllowCookie)。标准管理器的问题大部分时间都会出现,它会向最终用户弹出对话框,允许授权......(安全性再次出现!):

[ComImport, Guid("7b8a2d94-0ac9-11d1-896c-00c04Fb6bfc4")]
private class InternetSecurityManager
{
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b")]
private interface IInternetSecurityManager
{
    void Unused1();
    void Unused2();
    [PreserveSig]
    int MapUrlToZone([In, MarshalAs(UnmanagedType.BStr)] string pwszUrl, out int pdwZone, [In] int dwFlags);
    void Unused3();
    [PreserveSig]
    int ProcessUrlAction(string pwszUrl, int dwAction, ref int pPolicy, int cbPolicy, ref Guid pContext, int cbContext, int dwFlags, int dwReserved);
    // left undefined
}

public static SecurityZone MapUrlToZone(Uri uri)
{
    IInternetSecurityManager securityManager = (IInternetSecurityManager)new InternetSecurityManager();
    int zoneId;
    if (securityManager.MapUrlToZone(uri.ToString(), out zoneId, 0) < 0)
        return SecurityZone.NoZone;

    return (SecurityZone)zoneId;
}

private const int URLACTION_COOKIES = 0x00001A02;
private const int URLACTION_COOKIES_ENABLED = 0x00001A10;
private const int URLPOLICY_ALLOW = 0x00;
private const int URLPOLICY_DISALLOW = 0x03;
private const int PUAF_DEFAULT = 0x00000000;

public static bool TryAllowCookies(Uri uri)
{
    IInternetSecurityManager securityManager = (IInternetSecurityManager)new InternetSecurityManager();
    int policy = 0;
    Guid context = Guid.Empty;
    int hr = securityManager.ProcessUrlAction(uri.ToString(), URLACTION_COOKIES_ENABLED, ref policy, Marshal.SizeOf(policy), ref context, Marshal.SizeOf(context), PUAF_DEFAULT, 0);
    return (hr == 0) && policy == URLPOLICY_ALLOW;
}
祝你好运:)

答案 1 :(得分:0)

默认情况下,WebBrowser控件不允许这样做。出于安全原因,您可能不希望不同开发人员/公司的不同应用程序能够访问另一个应用程序创建的cookie信息。

但是,请查看此答案How to delete Cookies from windows.form?

这与通过javascript删除cookie有关,但您可以使用类似的方法,以便在每次加载应用程序时保持并创建站点cookie。