我正在发出基于 JSON 的 AJAX 请求,对于 MVC 控制器,我非常感谢 Phil Haack 的用 AJAX 防止 CSRF以及 Johan Driessen为 MVC 4 RC 更新的 Anti-XSRF。但是,当我将以 API 为中心的控制器转换为 Web API 时,我遇到了两种方法之间的功能明显不同并且我无法转换 CSRF 代码的问题。
ScottS最近提出了一个类似的问题,由 Darin Dimitrov回答。Darin 的解决方案包括实现一个调用 AntiForgery.Validate 的授权过滤器。不幸的是,这段代码对我不起作用(见下一段)而且——老实说——对我来说太先进了。
据我了解,Phil 的解决方案在没有表单元素的情况下发出 JSON 请求时克服了 MVC AntiForgery 的问题;表单元素由 AntiForgery.Validate 方法假定/预期。我相信这可能就是我对达林的解决方案也有问题的原因。我收到一个 HttpAntiForgeryException “所需的防伪表单字段 '__RequestVerificationToken' 不存在”。我确定令牌正在被发布(尽管根据 Phil Haack 的解决方案在标题中)。这是客户通话的快照:
$token = $('input[name=""__RequestVerificationToken""]').val();
$.ajax({
url:/api/states",
type: "POST",
dataType: "json",
contentType: "application/json: charset=utf-8",
headers: { __RequestVerificationToken: $token }
}).done(function (json) {
...
});
我尝试通过将 Johan 的解决方案与 Darin 的解决方案混合在一起来进行破解,并且能够让事情正常运行,但我正在引入 HttpContext.Current,不确定这是否合适/安全以及为什么我不能使用提供的 HttpActionContext。
这是我不雅的混搭。变化是 try 块中的 2 行:
public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
try
{
var cookie = HttpContext.Current.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null, HttpContext.Current.Request.Headers["__RequestVerificationToken"]);
}
catch
{
actionContext.Response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.Forbidden,
RequestMessage = actionContext.ControllerContext.Request
};
return FromResult(actionContext.Response);
}
return continuation();
}
我的问题是:
- 我认为达林的解决方案假设存在表单元素是否正确?
- 将 Darin 的 Web API 过滤器与 Johan 的 MVC 4 RC 代码混搭的优雅方法是什么?
提前致谢!