Iframe,跨域cookies,p3p策略以及Safari出现错误:未提供或无效的必需防伪令牌。

12

我一段时间以前问了这个问题(链接),发现IE会在iframe中阻止跨域的cookie,除非你设置一个p3p政策。目前为止,在ie中,p3p修复已经非常好用。然而,现在我们在safari中也遇到了同样的错误。

我找到了一篇有关safari不同p3p政策的文章。我添加了这段代码来设置p3p政策,但是我仍然收到“请求验证令牌”错误信息。

public static void SetP3PCompactPolicy()
{
    HttpContext current = HttpContext.Current;

    if (current.Request.UserAgent.ToLower().IndexOf("safari") >= 0)
        HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"");
    else
        HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
}

我不确定这些内容的含义,但它们在Safari(5)上无法运行。

另外,当我遇到服务器错误时,所有信息都会发送给我一个报告,包括所有的HTTP头。但是在这些错误中,P3P头并未传递过来。我不确定这是否是设计上的问题,或者这是否是正在发生的问题的指示器。

1个回答

9
问题在于Safari不允许在iframe中设置cookie,除非用户与该iframe进行交互。对于某些情况,这意味着点击链接。我找到了一个更好的解决方案,那就是进行重定向。
首先,在我的页面上放置了这个表单。实际上,我把它放在了每个在iframe中提供的视图中使用的masterpage中。
<% if(SecurityHelper.BrowserIsSafari) { %>
    <% using (Html.BeginForm("SafariRedirect", "Framed", FormMethod.Post, new { id="safari-fix-form" })) { %>
       <%: Html.Hidden("safariRedirectUrl")%>
    <% } %>
<% } %>

因为我只希望在用户使用safari浏览器时才能使其工作,所以我在一个静态辅助类中创建了这个属性来检查用户代理。

public static bool BrowserIsSafari
{
    get { return HttpContext.Current.Request.UserAgent.ToLower().IndexOf("safari") >= 0; }
}

然后,在我的控制器中,我有以下的操作

[HttpPost]
public ActionResult SafariRedirect(string safariRedirectUrl)
{
    Response.Cookies.Add(new HttpCookie("safari_cookie_fix", "cookie ok"));

    return Redirect(safariRedirectUrl);
}

在我的母版页中,在头部,我将脚本声明在相同的if语句中,该语句确定表单是否呈现。在我的脚本文件中,我有这个jquery:

$(function () {

    if ($.browser.safari == true && document.cookie.indexOf("safari_cookie_fix") == -1) {
        var url = location.href;

        $('#safariRedirectUrl').val(url);
        $('#safari-fix-form').submit();
    }

});

第一次加载iframe页面时,如果是Safari浏览器且cookie未设置,则会提交表单,设置cookie,并将用户重定向回相同的URL。

我添加了表单和带有cookies的Action,导致我的Safari出现递归问题。document.cookie.indexOf("safari_cookie_fix")总是为空。但在开发工具下,我看到了“cookie ok”。 - Yaroslav Bigus
我相当确定上述方法适用于Safari 4.5。但是,我最终还是清除了Cookie,因为IE中的安全设置也可能会阻止第三方Cookie。 - Josh
好的,我已经在我的服务器方法中添加了获取当前 cookies 并返回 JSONP 结果(true || false)的功能。并且使用这个结果代替 document.cookies。看起来能够正常工作。所以我建议你将此链接添加到我的问题中(https://dev59.com/Qm025IYBdhLWcg3wPzfL),然后我会将其标记为答案,并添加赏金;) - Yaroslav Bigus
只是一个提示,通常Chrome的用户代理中也有字符串“safari”,因此BrowserIsSafari可能需要重新编写... - David W.
1
不幸的是,这个漏洞似乎已经被修复了。请参见https://dev59.com/kGkw5IYBdhLWcg3wY5nq以获取更多讨论。 - eswald
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接