JsonRequestBehavior neden gereklidir?


384

Neden Json Request Behaviorihtiyaç duyulur?

HttpGetİstekleri eylemimle sınırlandırmak istersem, eylemi [HttpPost]niteliğiyle dekore edebilirim

Misal:

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

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

Neden [HttpPost]yeterli değil ?
Neden çerçeve ile sahip olduğumuz JsonRequestBehavior.AllowGether için "hata" JsonResult. Get isteklerini reddetmek istersem HttpPostözelliği ekleyeceğim .


Stackoverflow.com/questions/1625671/… 'a çok benziyorum (bu soruyu kendi sorumu ararken bulduğum halde :))
Jedidja

Çünkü GET'in idempotent olması beklenirken POST değildir. GET'ler -> POST'lar yaparak arabirimin anlambilimini değiştirirsiniz.
rism

19
Çünkü her yere acımasız argümanlar eklemek zorunda kalmazsanız kodunuz çok temiz görünüyordu.
John Shedletsky

Yanıtlar:


276

MVC varsayılan olarak DenyGet, HTTP GETmaruz kalmaya izin vermenin etkilerinin oluşmalarına izin verilmesini önleme olasılığını artırmak için JSON isteklerini içeren çok özel bir saldırıya karşı sizi koruma altına alır .

Bu, daha sonra çok geç olabileceğine karşıdır.

Not: İşlem yönteminiz hassas verileri döndürmezse, alma işlemine izin vermek güvenli olmalıdır.

Wrox ASP.NET MVC3 kitabımdan daha fazla okuma

Varsayılan olarak, ASP.NET MVC çerçevesi bir HTTP GET isteğine JSON yüküyle yanıt vermenize izin vermez. Bir GET'e yanıt olarak JSON göndermeniz gerekiyorsa, Json yönteminin ikinci parametresi olarak JsonRequestBehavior.AllowGet komutunu kullanarak davranışa açıkça izin vermeniz gerekir. Ancak, kötü niyetli bir kullanıcının JSON Hijacking olarak bilinen bir işlemle JSON yüküne erişme şansı vardır. Bir GET isteğinde JSON kullanarak hassas bilgileri döndürmek istemezsiniz. Daha fazla ayrıntı için Phil'in http://haacked.com/archive/2009/06/24/json-hijacking.aspx/ adresindeki gönderisine veya bu SO gönderisine bakın.

Haack, Phil (2011). Profesyonel ASP.NET MVC 3 (Wrox Programcı - Programcı) (Kindle Locations 6014-6020). Wrox. Kindle Sürümü.

İlgili StackOverflow sorusu

Çoğu tarayıcıda (Firefox 21, Chrome 27 veya IE 10 ile başlayarak), bu artık bir güvenlik açığı değildir.


20
Ancak soru hala devam ediyor: [HttpPost] neden yeterli değil?
gdoron Monica

4
Bence yeterli. Yalnızca bir HttpGet sonucunda verilerin geçmesine izin vermek istediğinizde AllowGet'e ihtiyacınız vardır. DensonGet, 1 parametresiyle Json'u (veri) çağırırsanız varsayılan değerdir.
danludwig

11
Benim sorum bu. Neden çerçeve ile JsonRequestBehavior.AllowGetsahip olduğum her JsonResult için bize "hata" . Alma isteğini reddetmek istersem HttpPostözelliği ekleyeceğim .
gdoron Monica

35
Sanırım bunun nedeni, pek çok insanın bu belirsiz kırılganlığın farkında olmaması. İsteği reddetmek isterseniz bunu [HttpPost] ile yapacağınızı söylüyorsunuz. Ancak MVC yazarları bu tür saldırılara karşı size bir koruma katmanı veriyor. 2. argümanı eklemek için çaba sarf etmeniz gerektiğinden, hangi verileri ortaya koyduğunuzu ve ne kadar hassas olduğunu düşünmek için bu zamanı ayırmalısınız.
danludwig

11
Yani şimdi API'mızı dağıtıyoruz ve potansiyel bir İSTEMCİ kaynaklı güvenlik açığı bulmak için "RESTful" arayüzlerine fiil karışıklığı ekliyoruz? Bu korkunç görünüyor ... ama tartışmayı takdir ediyorum.
Norman H

59

Kendinizi kolaylaştırmak için bir eylem dosyası da oluşturabilirsiniz.

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);
    }
}

ve onu eylemin üzerinde kullan

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

4
Ayrıca, RegisterGlobalFilters: filters.Add (new AllowJsonGetAttribute ()) öğesinde bunu varsayılan filtre olarak ayarlayabilirsiniz. Ancak, Filtre tüm eylem yöntemleri için uygulanacağından Özel Durumu kaldırmanız gerekir.
Vortex852456

8

Varsayılan olarak Jsonresult "Reddet"

Aşağıdaki gibi bir yöntemimiz varsa varsayalım

  [HttpPost]
 public JsonResult amc(){}

Varsayılan olarak "Almayı Reddet".

Aşağıdaki yöntemde

public JsonResult amc(){}

Get'e izin vermeniz veya kullanmanız gerektiğinde, JsonRequestBehavior.AllowGet kullanmamız gerekir.

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

5

AllowJsonGetAttribute öğesini mvc denetleyicilerine uygulanabilir hale getirerek @Arjen de Mooij'in cevabını biraz geliştirmek (yalnızca bireysel eylem yöntemleri değil):

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

Buna ihtiyacınız yok.

Eyleminizin HttpPostözniteliği varsa, o zaman JsonRequestBehavioraşırı yüklenmeyi ayarlamanıza ve aşırı yüklemeyi kullanmanıza gerek yoktur. JsonRequestBehaviorNumaralandırma olmadan her yöntem için aşırı yük vardır . İşte buradalar:

JsonRequestBehavior olmadan

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 ile

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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.