为什么需要JsonRequestBehavior?


384

为什么Json Request Behavior需要?

如果我想将HttpGet请求限制为我的操作,则可以使用[HttpPost]属性装饰该操作

例:

[HttpPost]
public JsonResult Foo()
{
    return Json("Secrets");
}

// Instead of:
public JsonResult Foo()
{
    return Json("Secrets", JsonRequestBehavior.AllowGet);
}

为什么还[HttpPost]不够?
为什么框架会用我们拥有的JsonRequestBehavior.AllowGet所有东西“困扰”我们JsonResult。如果我想拒绝获取请求,则添加HttpPost属性。


非常类似于stackoverflow.com/questions/1625671/…(尽管我发现这是一个搜索我自己的问题的方法:))
Jedidja 2014年

因为GET应该是幂等的,而POST不是。通过执行GET-> POST,可以更改接口的语义。
rism

19
因为如果您不必在每个地方添加繁琐的参数,您的代码看起来就会很干净。
John Shedletsky 2015年

Answers:


276

MVC的默认设置是DenyGet保护您免受涉及JSON请求的非常特定的攻击,以改善这种可能性,即在允许发生泄漏HTTP GET之前先考虑允许暴露的含义。

与之相反,之后可能为时已晚。

注意:如果您的操作方法未返回敏感数据,则允许获取是安全的。

从我的Wrox ASP.NET MVC3书中进一步阅读

默认情况下,ASP.NET MVC框架不允许您使用JSON负载响应HTTP GET请求。如果需要发送JSON作为对GET的响应,则需要使用JsonRequestBehavior.AllowGet作为Json方法的第二个参数来明确允许该行为。但是,恶意用户有可能通过称为JSON劫持的过程来访问JSON负载。您不想在GET请求中使用JSON返回敏感信息。有关更多详细信息,请参见http://haacked.com/archive/2009/06/24/json-hijacking.aspx/上的 Phil帖子 或此SO帖子。

Haack,Phil(2011)。专业的ASP.NET MVC 3(从程序员到程序员的近似编程器)(Kindle位置6014-6020)。约克 Kindle版。

相关StackOverflow问题

对于最新的浏览器(从Firefox 21,Chrome 27或IE 10开始),这不再是一个漏洞。


20
但是问题仍然存在:[HttpPost]为什么还不够?
gdoron支持Monica 2011年

4
我认为就足够了。仅当您要允许数据作为HttpGet的结果传递时,才需要AllowGet。如果您使用1个参数调用Json(data),则默认为DenyGet。
danludwig 2011年

11
这是我的问题。为什么框架JsonRequestBehavior.AllowGet为我拥有的每个JsonResult都“困扰”了我们。如果我想拒绝获取请求,则添加HttpPost属性。
gdoron支持Monica 2011年

35
我认为这是因为没有多少人意识到此隐患。您说如果要拒绝该请求,则可以使用[HttpPost]进行。但是,MVC作者为您提供了针对此类攻击的现成保护层。由于您需要努力添加第二个参数,因此您应该花时间考虑要公开的数据及其敏感性。
danludwig 2011年

11
因此,现在我们弄乱了我们的API,并向“ RESTful”接口添加了动词混淆,以解决潜在的CLIENT驱动的漏洞?这看起来很糟糕...但是我很高兴进行讨论。
诺曼^ h

59

为了使自己更轻松,您还可以创建一个actionfilter属性

public class AllowJsonGetAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;

        if (jsonResult == null)
            throw new ArgumentException("Action does not return a JsonResult, 
                                                   attribute AllowJsonGet is not allowed");

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;            

        base.OnResultExecuting(filterContext);
    }
}

并用在你的行动上

[AllowJsonGet]
public JsonResult MyAjaxAction()
{
    return Json("this is my test");
}

4
此外,您可以在RegisterGlobalFilters中将其设置为默认过滤器:filters.Add(新的AllowJsonGetAttribute())。但是,由于过滤器将应用于所有操作方法,因此您必须删除异常。
Vortex852456

8

默认情况下,Jsonresult“ Deny get”

假设我们有如下方法

  [HttpPost]
 public JsonResult amc(){}

默认情况下为“拒绝获取”。

在下面的方法

public JsonResult amc(){}

当您需要allowget或使用get时,我们必须使用JsonRequestBehavior.AllowGet。

public JsonResult amc()
{
 return Json(new Modle.JsonResponseData { Status = flag, Message = msg, Html = html }, JsonRequestBehavior.AllowGet);
}

5

通过使AllowJsonGetAttribute适用于mvc控制器(而不仅仅是个别的操作方法),可以稍微改善@Arjen de Mooij的答案:

using System.Web.Mvc;
public sealed class AllowJsonGetAttribute : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext context)
    {
        var jsonResult = context.Result as JsonResult;
        if (jsonResult == null) return;

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;
        if (jsonResult == null) return;

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        base.OnResultExecuting(filterContext);
    }
}

2

您不需要它。

如果您的操作具有HttpPost属性,那么您无需费心设置JsonRequestBehavior并使用没有该属性的重载。没有JsonRequestBehavior枚举的每种方法都有一个重载。他们来了:

没有JsonRequestBehavior

protected internal JsonResult Json(object data);
protected internal JsonResult Json(object data, string contentType);
protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding);

使用JsonRequestBehavior

protected internal JsonResult Json(object data, JsonRequestBehavior behavior);
protected internal JsonResult Json(object data, string contentType, 
                                   JsonRequestBehavior behavior);
protected internal virtual JsonResult Json(object data, string contentType, 
    Encoding contentEncoding, JsonRequestBehavior behavior);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.