【发布时间】:2017-12-02 09:03:14
【问题描述】:
我有一个应该是 iFramed 的 MVC 视图。它的几个实例可能是 iFramed 在同一个主机页面中。在我看来,我有这个:
@Html.AntiForgeryToken()
我用它来确保对 web api 的调用仅来自此页面。我的主机页面可能如下所示:
<iframe src="http://myserver.com/myview?someparameters=0000"></iframe>
<iframe src="http://myserver.com/myview?someparameters=0001"></iframe>
<iframe src="http://myserver.com/myview?someparameters=0002"></iframe>
在我看来,我获取令牌并将其提交到标题中,以便我可以在我的 API 中检查它:
var headers = actionContext.Request.Headers;
var headerToken = headers.Contains("__RequestVerificationToken") ? headers.GetValues("__RequestVerificationToken").FirstOrDefault() : null;
var cookie = headers.GetCookies("__RequestVerificationToken").FirstOrDefault()?["__RequestVerificationToken"]?.Value;
AntiForgery.Validate(cookie,headerToken);
我遇到的问题是,在我的主机页面中,所有三个视图都是并行加载的。结果,他们都在隐藏字段中获得了自己的随机令牌并尝试设置 cookie。但是,虽然可以有三个独立的独立隐藏输入令牌,但只能有一个 cookie。所以在这三个请求中,两个会失败,一个会成功。重新加载页面将使所有三个再次工作,大概是因为此时它们都获得了相同的防伪令牌(因为它属于会话 - 如果我理解正确的话)。
那么我该如何避免这种情况呢?如何确保他们都获得相同的令牌?
【问题讨论】:
-
您可以通过不使用 iframe 来避免这种情况。所以问题是:你能改变设计吗?你需要 iframe 吗?每个 iframe 是否都包含一个表单?因为防伪令牌只会用于发布信息。
-
@RuardvanElburg - 不是真的。这个想法是,这是一个小部件类型的东西,我们的客户可以放到他们自己的页面上。问题是他们想在同一个页面上放置几个,周围有自己的内容。 iframed 页面本身必须进行一些后端调用,这些调用通过检查令牌来保护,但也许我必须重新考虑这一点。
-
还有一个 javascript 解决方案?
-
@HoomanBahreini - 令牌不是问题。 Cookie 是。
-
@HoomanBahreini - 这是一个仅限 http 的 cookie。无法从 javascript 访问它。此外,检查它是否已经设置仍然会导致完全相同的竞争条件。事实上,这正是
@Html.AntiForgeryToken()内部发生的事情。它检查是否已经设置了 cookie,如果没有,则创建一个新的并在 html 中创建一个隐藏的input标记。问题是两个请求同时进来,而且都没有cookie。
标签: c# asp.net-mvc iframe cookies