2012-09-09 10 views
10

मुझे @Html.AntiForgeryToken() के साथ गंभीर समस्या का सामना करना पड़ रहा है। मेरे पास एक रजिस्टर नियंत्रक है जिसके पास नए सदस्यों को बनाने/पंजीकृत करने के लिए एक दृश्य दृश्य था। इसी कारण से मैंने अपने मुख्य सबमिट फॉर्म में किसी भी SALT का उपयोग किये बिना @Html.AntiForgeryToken() का उपयोग किया। अब मैं उपयोगकर्ता नाम को सत्यापित करना चाहता हूं यदि यह मेरे उपयोगकर्ता नाम टेक्स्टबॉक्स की धुंधली घटना पर डेटाबेस पर पहले से मौजूद है। इस मान्यता के लिए मैं 'मान्यता' नामक एक नए नियंत्रक लिखा था और एक निरंतर सत्यापन नमक के साथ एक विधि ने लिखा है:क्या एक पृष्ठ में 2 अलग-अलग रूपों में एकाधिक @ Html.AntiForgeryToken() का उपयोग करना संभव/सही है?

[HttpPost] 
    [ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)] 
    public ActionResult username(string log) { 
     try { 
      if (log == null || log.Length < 3) 
       return Json(log, JsonRequestBehavior.AllowGet); 

      var member = Membership.GetUser(log); 

      if (member == null) { 
       //string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$"; 
       string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}"; 
       if (Regex.IsMatch(log, userPattern)) 
        return Json(log, JsonRequestBehavior.AllowGet); 
      } 

     } catch (Exception ex) { 
      CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()"); 
      return Json(log, JsonRequestBehavior.AllowGet); 
     } 
     //found e false 
     return Json(log, JsonRequestBehavior.AllowGet); 

    } 

विधि ठीक काम कर रहा है। मैंने HTTP के साथ [ValidateAntiForgeryToken] के बिना एनोटेशन प्राप्त किया था और यह मुझे अपेक्षित परिणाम दे रहा था।

मैं googled और इनमें से दिए गए समाधान से कोई भी के कई काम कर रहे हैं की जाँच की थी। मेरे सत्यापन नियंत्रक के लिए मैंने एक ही पृष्ठ में एक और प्रपत्र का उपयोग किया और एंटी-जालसाजी टोकन में एक एसएएलटी का इस्तेमाल किया।

उदाहरण: मुख्य प्रस्तुत फार्म के लिए पहले विरोधी जालसाजी टोकन:

@using (Html.BeginForm ("बनाएँ", "रजिस्टर")) { @ Html.AntiForgeryToken() @ Html.ValidationSummary (सही) ...}

दूसरा विरोधी जालसाजी टोकन:

<form id="__AjaxAntiForgeryForm" action="#" method="post"> 
    @Html.AntiForgeryToken(SALT) 
</form> 

और जावास्क्रिप्ट में मैं इस

<script type="text/javascript" defer="defer"> 
    $(function() { 
     AddAntiForgeryToken = function (data) { 
      data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val(); 
      return data; 
     }; 

     if ($("#LogName").length > 0) { 

      $("#LogName").blur(function() { 
       var user = $("#LogName").val(); 
       var logValidate = "/Validation/username/"; 
       //var URL = logValidate + user; 
       //var token = $('#validation input[name=__RequestVerificationToken]').val(); 
       data = AddAntiForgeryToken({ log: user }); 

       $.ajax({ 
        type: "POST", 
        dataType: "JSON", 
        url: logValidate, 
        data: data, 
        success: function (response) { 
         alert(response); 
        } 
       }); 

      }); 

     } 
    }); 
</script> 

मेरी फ़ायरबग में मैं यह मिल गया प्रयोग किया है: पारित कर दिया के रूप में लेकिन कुकी अनुभाग मैं एक गुजर तुलना में एक अलग कुकी मिल में

log=admin&__RequestVerificationToken=NO8Kds6B2e8bexBjesKlwkSexamsruZc4HeTnFOlYL4Iu6ia%2FyH7qBJcgHusekA50D7TVvYj%2FqB4eZp4VDFlfA6GN5gRz7PB%2ByZ0AxtxW4nT0E%2FvmYwn7Fvo4GzS2ZAhsGLyQC098dfIJaWCSiPcc%2FfD00FqKxjvnqmxhXvnEx2Ye83LbfqA%2F4XTBX8getBeodwUQNkcNi6ZtAJQZ79ySg%3D%3D 

: वास्तविक कुकी:

ws5Dt2if6Hsah rW2nDly P3cW1smIdp1Vau 0TXOK1w0ctr0BCso/nbYu w9blq/QcrXxQLDLAlKBC3Tyhp5ECtK MxF4hhPpzoeByjROUG0NDJfCAlqVVwV5W6lw9ZFp/VBcQmwBCzBM/36UTBWmWn6pMM2bqnyoqXOK4aUZ4= 

मुझे लगता है कि ऐसा इसलिए है क्योंकि मैंने एक पृष्ठ में 2 विरोधी जालसाजी टोकन का उपयोग किया था। लेकिन मेरे दिमाग में मुझे 2 का उपयोग करना चाहिए क्योंकि पहले व्यक्ति सबमिट होने के लिए उत्पन्न हो रहा है और अगले को सत्यापन सत्यापित करने की आवश्यकता है। हालांकि, यह मेरा अनुमान है और मुझे लगता है कि मैं गलत हूं और इस कारण से मुझे आपके लोगों की मदद चाहिए।

किसी को भी तथ्यों कि मैं दो विरोधी जालसाजी या एक का उपयोग करना चाहिए के बारे में समझाएं कर सकते हैं?

आप सभी पहले से धन्यवाद ....

उत्तर

8

अंत में संघर्ष के 8 घंटे मुझे एक समाधान देता है।

पहली चीजें पहले, हां पृष्ठ में 2 विरोधी-जालसाजी टोकन का उपयोग करने के लिए कोई हानि नहीं है। और दूसरा टोकन प्रदान करने के साथ कुकीज़ से मेल खाने की कोई ज़रूरत नहीं है। टोकन प्रदान करना हमेशा अलग होगा और सर्वर में सत्यापित किया जाएगा।

विरोधी जालसाजी टोकन अगर हम [HttpGet] एक्शन क्रियाओं का उपयोग काम नहीं करता है .. क्योंकि विरोधी जालसाजी के सत्यापन प्रक्रिया में टोकन अनुरोध से Request.Form['__RequestVerificationToken'] मूल्य की पुन: प्राप्त करने द्वारा मान्य है।रेफरी: Steven Sanderson's blog: prevent cross...

समाधान:

मेरे संशोधित नियंत्रक:

[HttpPost] 

     [ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)] 
//change the map route values to accept this parameters. 
     public ActionResult username(string id, string __RequestVerificationToken) { 
     string returnParam = __RequestVerificationToken; 

     try { 
      if (id == null || id.Length < 3) 
       return Json(returnParam, JsonRequestBehavior.AllowGet); 

      var member = Membership.GetUser(id); 

      if (member == null) { 
       //string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$"; 
       string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}"; 
       if (Regex.IsMatch(id, userPattern)) 
        return Json(returnParam, JsonRequestBehavior.AllowGet); 
      } 

     } catch (Exception ex) { 
      CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()"); 
      return Json(returnParam, JsonRequestBehavior.AllowGet); 
     } 
     //found e false 
     return Json(returnParam, JsonRequestBehavior.AllowGet); 
    } 

एक ही पृष्ठ में मेरी पहली प्रपत्र:

@using (Html.BeginForm("Create", "Register")) { 

    @Html.AntiForgeryToken(ApplicationEnvironment.SALT) 

    @Html.ValidationSummary(true) 
    .... 
} 

एक ही पृष्ठ में मेरी दूसरी प्रपत्र:

**<form id="validation"> 
    <!-- there is harm in using 2 anti-forgery tokens in one page--> 
    @Html.AntiForgeryToken(ApplicationEnvironment.SALT) 
    <input type="hidden" name="id" id="id" value="" /> 
</form>** 

मेरा jQuery इस बात को हल करने के लिए:

$("#LogName").blur(function() { 
      var user = $("#LogName").val(); 
      var logValidate = "/Validation/username/"; 
      $("#validation #id").val(user); 
      **var form = $("#validation").serialize(); // a form is very important to verify anti-forgery token and data must be send in a form.** 

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

      $.ajax({ 
       **type: "POST", //method must be POST to validate anti-forgery token or else it won't work.** 
       dataType: "JSON", 
       url: logValidate, 
       data: form, 
       success: function (response) { 
        alert(response); 
       } 
      }); 
     });