使用 MVC 4 RC 为 Web API 实现 ValidatingAntiForgeryToken 属性的问题 [英] Problems implementing ValidatingAntiForgeryToken attribute for Web API with MVC 4 RC

查看:34
本文介绍了使用 MVC 4 RC 为 Web API 实现 ValidatingAntiForgeryToken 属性的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作基于 JSON 的 AJAX 请求,并且使用 MVC 控制器非常感谢 Phil Haack 的 使用 AJAX 防止 CSRF 和 Johan Driessen 的 为 MVC 4 RC 更新了反 XSRF.但是,当我将以 API 为中心的控制器转换为 Web API 时,我遇到了两种方法之间的功能明显不同的问题,并且我无法转换 CSRF 代码.

I'm making JSON-based AJAX requests and, with MVC controllers have been very grateful to Phil Haack for his Preventing CSRF with AJAX and, Johan Driessen's Updated Anti-XSRF for MVC 4 RC. But, as I transition API-centric controllers to Web API, I'm hitting issues where the functionality between the two approaches is markedly different and I'm unable to transition the CSRF code.

ScottS 最近提出了一个类似的问题,即由 Darin Dimitrov 回答.Darin 的解决方案包括实现一个调用 AntiForgery.Validate 的授权过滤器.不幸的是,这段代码对我不起作用(见下一段),而且 - 老实说 - 对我来说太高级了.

ScottS raised a similar question recently which was answered by Darin Dimitrov. Darin's solution involves implementing an authorization filter which calls AntiForgery.Validate. Unfortunately, this code does not work for me (see next paragraph) and - honestly - is too advanced for me.

据我所知,Phil 的解决方案克服了 MVC AntiForgery 在没有表单元素的情况下发出 JSON 请求时的问题;表单元素由 AntiForgery.Validate 方法假定/预期.我相信这可能就是我对 Darin 的解决方案也有问题的原因.我收到 HttpAntiForgeryException 所需的防伪表单字段 '__RequestVerificationToken' 不存在".我确定令牌正在被发布(尽管在每个 Phil Haack 的解决方案的标题中).这是客户通话的快照:

As I understand it, Phil's solution overcomes the problem with MVC AntiForgery when making JSON requests in the absence of a form element; the form element is assumed/expected by the AntiForgery.Validate method. I believe that this may be why I'm having problems with Darin's solution too. I receive an HttpAntiForgeryException "The required anti-forgery form field '__RequestVerificationToken' is not present". I am certain that the token is being POSTed (albeit in the header per Phil Haack's solution). Here's a snapshot of the client's call:

$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.

I tried a hack by mashing together Johan's solution with Darin's and was able to get things working but am introducing HttpContext.Current, unsure whether this is appropriate/secure and why I can't use the provided HttpActionContext.

这是我不雅的混搭.变化是 try 块中的 2 行:

Here's my inelegant mash-up.. the change is the 2 lines in the try block:

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 的解决方案假定表单元素存在是正确的吗?
  • 将 Darin 的 Web API 过滤器与 Johan 的 MVC 4 RC 代码混搭的优雅方式是什么?

提前致谢!

推荐答案

您可以尝试阅读标题:

var headers = actionContext.Request.Headers;
var cookie = headers
    .GetCookies()
    .Select(c => c[AntiForgeryConfig.CookieName])
    .FirstOrDefault();
var rvt = headers.GetValues("__RequestVerificationToken").FirstOrDefault();
AntiForgery.Validate(cookie != null ? cookie.Value : null, rvt);

注意:GetCookies 是存在于 HttpRequestHeadersExtensions 类中的一个扩展方法,它是 System.Net.Http.Formatting.dll 的一部分.它很可能存在于 C:Program Files (x86)Microsoft ASP.NETASP.NET MVC 4AssembliesSystem.Net.Http.Formatting.dll

Note: GetCookies is an extension method that exists in the class HttpRequestHeadersExtensions which is part of System.Net.Http.Formatting.dll. It will most likely exist in C:Program Files (x86)Microsoft ASP.NETASP.NET MVC 4AssembliesSystem.Net.Http.Formatting.dll

这篇关于使用 MVC 4 RC 为 Web API 实现 ValidatingAntiForgeryToken 属性的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆