¿Por qué se necesita JsonRequestBehavior?
¿Por qué es Json Request Behavior
necesario?
Si quiero restringir las HttpGet
solicitudes a mi acción puedo decorar la acción con el [HttpPost]
atributo
Ejemplo:
[HttpPost]
public JsonResult Foo()
{
return Json("Secrets");
}
// Instead of:
public JsonResult Foo()
{
return Json("Secrets", JsonRequestBehavior.AllowGet);
}
¿Por qué no es [HttpPost]
suficiente?
Por qué el marco nos "molesta" con JsonRequestBehavior.AllowGet
cada cosa JsonResult
que tenemos. Si quiero rechazar solicitudes de obtención, agregaré el HttpPost
atributo.
MVC tiene como valor predeterminado DenyGet
protegerlo contra un ataque muy específico que involucra solicitudes JSON para mejorar la probabilidad de que las implicaciones de permitir HTTP GET
la exposición se consideren antes de permitir que ocurran.
Esto se opone a después, cuando podría ser demasiado tarde.
Nota: Si su método de acción no devuelve datos confidenciales, entonces debería ser seguro permitir la obtención.
Lecturas adicionales de mi libro Wrox ASP.NET MVC3
De forma predeterminada, el marco ASP.NET MVC no le permite responder a una solicitud HTTP GET con una carga útil JSON. Si necesita enviar JSON en respuesta a un GET, deberá permitir explícitamente el comportamiento utilizando JsonRequestBehavior.AllowGet como segundo parámetro del método Json. Sin embargo, existe la posibilidad de que un usuario malintencionado pueda obtener acceso a la carga útil JSON mediante un proceso conocido como secuestro de JSON. No desea devolver información confidencial utilizando JSON en una solicitud GET. Para obtener más detalles, consulte la publicación de Phil en http://haacked.com/archive/2009/06/24/json-hijacking.aspx/ o esta publicación SO.
Haack, Phil (2011). ASP.NET MVC 3 profesional (programador a programador Wrox) (ubicaciones Kindle 6014-6020). Wrox. Versión Kindle.
Pregunta relacionada con StackOverflow
Con los navegadores más recientes (comenzando con Firefox 21, Chrome 27 o IE 10), esto ya no es una vulnerabilidad.
Para ponértelo más fácil, también puedes crear un atributo de filtro de acción.
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);
}
}
y úsalo en tu acción
[AllowJsonGet]
public JsonResult MyAjaxAction()
{
return Json("this is my test");
}
Por defecto Jsonresult "Denegar obtención"
Supongamos que tenemos un método como el siguiente
[HttpPost]
public JsonResult amc(){}
De forma predeterminada, "Denegar obtención".
En el siguiente método
public JsonResult amc(){}
Cuando necesite permitir o usar get, tenemos que usar JsonRequestBehavior.AllowGet.
public JsonResult amc()
{
return Json(new Modle.JsonResponseData { Status = flag, Message = msg, Html = html }, JsonRequestBehavior.AllowGet);
}
Mejorando un poco la respuesta de @Arjen de Mooij haciendo que AllowJsonGetAttribute sea aplicable a los controladores mvc (no solo a los métodos de acción individuales):
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);
}
}