¿Por qué se necesita JsonRequestBehavior?

Resuelto gdoron asked hace 13 años • 5 respuestas

¿Por qué es Json Request Behaviornecesario?

Si quiero restringir las HttpGetsolicitudes 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.AllowGetcada cosa JsonResultque tenemos. Si quiero rechazar solicitudes de obtención, agregaré el HttpPostatributo.

gdoron avatar Dec 11 '11 21:12 gdoron
Aceptado

MVC tiene como valor predeterminado DenyGetprotegerlo contra un ataque muy específico que involucra solicitudes JSON para mejorar la probabilidad de que las implicaciones de permitir HTTP GETla 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.

danludwig avatar Dec 11 '2011 14:12 danludwig

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");
}
Arjen de Mooij avatar Feb 25 '2015 12:02 Arjen de Mooij

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);
}
Deepakmahajan avatar Feb 14 '2012 13:02 Deepakmahajan

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);
    }
}
XDS avatar Dec 07 '2016 08:12 XDS