2009-08-28 11 views
8

Obecnie rozwijam aplikację MVC w ASP.net. Używam AJAX.ActionLink, aby zapewnić link do usunięcia na liście rekordów, jednak jest to bardzo niebezpieczne. Położyłem to:ASP.net MVC AntiForgeryToken przez AJAX

<AcceptVerbs(HttpVerbs.Post)> 

Nad funkcją do usuwania, która zatrzymuje wywoływanie funkcji po prostu przez URL. Jednak druga dziura bezpieczeństwa, który nadal istnieje to, że jeśli miałbym zrobić prostą stronę HTML z tej treści:

<form action="http://foo.com/user/delete/260" method="post"> 
<input type="submit" /> 
</form> 

Byłoby jeszcze zostać perfoming post, ale z innego miejsca.

Czy jest możliwe aby użyć AntiForgeryToken z AJAX actionlink? Jeśli tak, czy jest to bezpieczne podejście? Czy nie mam jeszcze więcej luk w zabezpieczeniach?

Odpowiedz

2

Nie wiem dokładnie o AJAX ActionLink, ale można to zrobić na stronie WebForms, aby opublikować działanie MVC z atrybutami [AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken].

Można użyć refleksji uzyskać w metodach stosowanych MVC ustawić wejście cookies i formularz dopasowanie używany do sprawdzania poprawności MVC.

Zobacz tę odpowiedź: Using an MVC HtmlHelper from a WebForm

9

Zapraszamy do obejrzenia tej blog post.

że masz metody działania jak tym:

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] public ActionResult DeleteAccount(int accountId) { // delete stuff }

I ty nazywasz go poprzez:

$.post('/home/DeleteAccount', { accountId: 1000 }, function() { alert('Account Deleted.'); });

Ponieważ POST nie obejmuje AntiForgeryToken, to się nie powiedzie.

Na szczęście, to nie zajmuje dużo umysłowego, aby to naprawić. Wszystkim składnikom bocznym klienta AntiForgeryToken jest umieszczany token w ukrytym polu . Tak więc, musisz tylko wyciągnąć te dane i zawrzeć je w swoim wywołaniu AJAX.

var token = $('input[name=__RequestVerificationToken]').val();

$.post('/home/DeleteAccount', { accountId: 1000, '__RequestVerificationToken': token }, function() { alert('Account Deleted.'); });

Należy pamiętać, że jeśli masz wiele formularzy na stronie z wieloma AntiForgeryTokens, trzeba będzie określić, który z nich chcesz w selektor jQuery. Innym haczyka jest jeśli używasz serializeArray() funkcję jQuery, musisz by go dodać trochę inaczej:

var formData = $('#myForm').serializeArray(); var token = $('input[name=__RequestVerificationToken]').val(); formData.push({ name: '__RequestVerificationToken', value: token });

$.post('/home/DeleteAccount', formData, function() { alert('Account Deleted.'); });

Update: Link został naprawiony.

+1

linkujące nie żyje – Keith

+0

Nie trzeba formData.push ({name: '__RequestVerificationToken', wartość: żeton}); od serializeArray() zwróci wszystkie wejścia formularza, które zawierają __RequestVerificationToken ukryte pole. –

+0

Tak trzeba zrobić to na słupach AJAX (przy użyciu bieżącego MVC 4 i MS dyskretny AJAX = jQuery) !!! –

0

Nie używałem żadnych pomocników Ajax siebie, ale nie widzę żadnego powodu, dlaczego nie można używać łącza. Osobiście użyłbym programu obsługi zdarzeń onload, aby dyskretnie utworzyć łącze z samego formularza, a następnie usunąć formularz.

6

Można użyć AntiForgeryToken z Ajax.ActionLink ale trzeba ręcznie wstawić AntiForgeryToken w nagłówku żądania tak:

function GetAntiForgeryToken(){ 
    var tokenWindow = window; 
    var tokenName = "__RequestVerificationToken"; 
    var tokenField = $(tokenWindow.document).find("input[type='hidden'][name='" +  tokenName + "']"); 
    if (tokenField.length == 0) {return null;} 
    else { 
     return { 
     name: tokenName, 
     value: tokenField.val() 
     }; 
    } 
}; 

Wtedy możemy użyć $ .ajaxPrefilter aby wstawić go do nagłówka:

$.ajaxPrefilter(
    function (options, localOptions, jqXHR) { 
     var token = GetAntiForgeryToken(); 
     jqXHR.setRequestHeader(token.name, token.value); 
    } 
); 

napisałem posta o tym here. Mam nadzieję że to pomoże!

+0

To będzie wysyłać token w nagłówku, ale [ValidateAntiForgeryToken] filtr wymaga to w danych formularza ... – iGanja

6

Zastosowanie AntiForgeryToken z Ajax.ActionLink

Oprócz jjwhite01 reakcji; wstawić token danych formularzy, należy option.data w filtr wstępny

$.ajaxPrefilter(
    function (options, localOptions, jqXHR) { 
     if (options.type !== "GET") { 
      var token = GetAntiForgeryToken(); 
      if (token !== null) { 
       if (options.data.indexOf("X-Requested-With") === -1) { 
        options.data = "X-Requested-With=XMLHttpRequest" + (options.data === "") ? "" : "&" + options.data; 
       } 
       options.data = options.data + "&" + token.name + '=' + token.value; 
      } 
     } 
    } 
); 
+1

Dyskretne skrypt ajax w MVC 4 zawiera - options.data.push ({name: „X-Requested-Z ”wartość«XMLHttpRequest»}) - więc sprawdzanie i dodając do tego jest już niepotrzebny – Brent

Powiązane problemy