2010-11-25 109 views
2

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

但是,由于某些原因,Cookie似乎并未在WebBrowser控件内部工作。它们可以在IE浏览器以及Firefox和Chrome浏览器中正常工作(因此项目可以正确隐藏),但在通过WPF WebBrowser控件查看时,它们永远不会隐藏。

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

这里有一个浏览器中的网页(其中Cookie的工作)之一:

Help pane inside a browser

而这里的内部应用程序完全相同的网页:

Help pane inside the application

这额外的内容应该只在使用该软件的前几次才能看到(即它应该在该网页的N次浏览后隐藏),但是因为我无法让Cookie工作,所以它始终可见。

回答

6

饼干在Internet Explorer(或托管版本)的处理是联系在一起的IE自身的“URL安全区域”的概念,DOC在这里:About URL security Zones

因此,IE决定使用施加到URL各种alogorithms的URL区域。根据区域的不同,您的托管浏览器可能会或可能不会支持会话或永久性Cookie。

奇怪的是,当我创建一个小型的WPF示例时,将Web浏览器添加到它并导航到此持久cookie测试仪使用页面: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; 
} 

祝你好运:)

0

默认情况下,WebBrowser控件不允许使用此功能。出于安全原因,您可能不希望来自不同开发人员/公司的不同应用程序能够访问其他应用程序创建的Cookie信息。

然而,看看这个答案How to delete Cookies from windows.form?

,涉及到通过JavaScript删除Cookie,但你可以以坚持和创建站点的cookie每个应用程序被加载时使用类似的方法。

+0

我不理解这个答案。是不是cookie绑定到页面,而不是绑定到应用程序?这是设置Cookie的页面。该应用程序是完全被动的。 – 2010-12-16 11:15:10

+0

我已经更新了这个问题,希望能够更好地说明我想在这里实现的目标。 Cookie不是由应用程序创建的,它们都是在服务器端创建的。该应用只是显示网页。 – Wilka 2010-12-16 12:42:54