WPF WebBrowser控件中的持久性cookie?

Wil*_*lka 2 browser cookies wpf wpf-controls

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

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

在WPF WebBrowser控件中使用cookie有什么特别之处吗?它似乎表现得好像所有的cookie都只存储在内存中,而不是存储在磁盘上.

这是浏览器中的一个页面(cookie工作的地方):

浏览器中的帮助窗格

这里是应用程序内的完全相同的页面:

应用程序内的帮助窗格

这个附加内容应该只在使用软件的前几次可见(即它应该在该网页的N个视图之后隐藏),但是因为我无法获得cookie,所以它总是可见的.

Sim*_*ier 6

Internet Explorer(或托管版本)中的Cookie处理与IE自身的"URL安全区域"概念相关联,此处为doc:关于URL安全区域

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

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

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

如果您自己托管IE,您可以实现自己的安全区域句柄,如下所述:在此处实现自定义安全管理器和示例:示例:Secumgr.exe覆盖WebBrowser主机的安全管理器,但您依赖于WPF的Web浏览器不允许任何覆盖...您可以访问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;
}
Run Code Online (Sandbox Code Playgroud)

祝好运 :)