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
属性。#1 楼
MVC的默认值为DenyGet
,以保护您免受涉及JSON请求的非常特定的攻击,以改善可能性,即在允许HTTP GET
暴露之前先考虑允许q4312079q暴露的含义。 与之相反,这可能事后为时已晚。
注意:如果您的操作方法未返回敏感数据,则允许获取是安全的。
我的Wrox ASP.NET MVC3书的进一步阅读
默认情况下,ASP.NET MVC框架不允许您响应
一个带有JSON负载的HTTP GET请求。如果您需要在JSON中发送对GET的响应,则需要使用JsonRequestBehavior.AllowGet作为Json
方法的第二个参数,通过
显式允许该行为。但是,恶意用户有可能通过称为JSON劫持的过程来访问JSON有效负载。您
不想在GET请求中使用JSON返回敏感信息。有关
的更多详细信息,请参见Phil的帖子,网址为
http://haacked.com/archive/2009/06/24/json-hijacking.aspx/或此SO帖子。
Haack,Phil(2011)。专业的ASP.NET MVC 3(从Wrox编程器转换为
编程器)(Kindle位置6014-6020)。约克Kindle版。
相关的StackOverflow问题
对于最新的浏览器(从Firefox 21,Chrome 27或IE 10开始),这不再是一个漏洞。
评论
但是问题仍然存在:[HttpPost]为什么还不够?
– gdoron支持Monica
2011-12-11 14:30
我认为就足够了。仅当您要允许数据作为HttpGet的结果传递时,才需要AllowGet。如果您使用1个参数调用Json(data),则默认为DenyGet。
– danludwig
2011-12-11 14:36
这是我的问题。为什么框架为我拥有的每个JsonResult都使用JsonRequestBehavior.AllowGet来“调试”我们。如果我想拒绝获取请求,我将添加HttpPost属性。
– gdoron支持Monica
2011-12-11 14:38
我认为这是因为没有多少人意识到此隐患。您说如果要拒绝该请求,请使用[HttpPost]来完成。但是,MVC作者为您提供了一种针对此类攻击的即用型保护。由于您需要努力添加第二个参数,因此您应该花时间考虑要公开的数据及其敏感程度。
– danludwig
2011-12-11 14:42
因此,现在我们弄乱了我们的API,并向“ RESTful”接口添加了动词混淆,以解决潜在的CLIENT驱动的漏洞?这看起来很糟糕...但是我很感谢大家的讨论。
– Norman H
13年4月30日在19:34
#2 楼
为了让您自己更轻松,您还可以创建一个动作过滤器属性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");
}
评论
另外,您可以在RegisterGlobalFilters中将其设置为默认过滤器:filters.Add(new AllowJsonGetAttribute())。但是,由于过滤器将应用于所有操作方法,因此您必须删除异常。
–Vortex852456
18年1月26日在8:54
#3 楼
默认情况下,Jsonresult“拒绝获取”如果我们有如下所示的方法
[HttpPost]
public JsonResult amc(){}
默认情况下为“拒绝获取”。
在以下方法中
public JsonResult amc(){}
当需要允许get或使用get时,我们必须使用JsonRequestBehavior.AllowGet。
public JsonResult amc()
{
return Json(new Modle.JsonResponseData { Status = flag, Message = msg, Html = html }, JsonRequestBehavior.AllowGet);
}
#4 楼
通过使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);
}
}
#5 楼
您不需要它。如果您的操作具有
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);
评论
非常类似于stackoverflow.com/questions/1625671/…(尽管我发现这是一个搜索我自己的问题的方法:))因为GET应该是幂等的,而POST不是。通过进行GET-> POST,可以更改接口的语义。
因为如果不必在每个地方添加繁琐的参数,您的代码看起来就会很干净。