2013-02-17 14 views
20

@ Html.AntiForgeryToken() renders छिपे हुए इनपुटकैसे छिपा इनपुट के बिना AntiForgeryToken मूल्य प्राप्त करने के

<input name="__RequestVerificationToken" type="hidden" value="GuiNIwhIJZjINHhuS_8FenaFDXIiaE" /> 

मैं कैसे टोकन मान ही मिल सकता है? इस तरह बदसूरत कोड के बिना:

public static IHtmlString AntiForgeryTokenValue(this HtmlHelper htmlHelper) { 
     var field = htmlHelper.AntiForgeryToken().ToHtmlString(); 
     var beginIndex = field.IndexOf("value=\"") + 7; 
     var endIndex = field.IndexOf("\"", beginIndex); 
     return new HtmlString(field.Substring(beginIndex, endIndex - beginIndex)); 
    } 

उत्तर

13

MVC के विरोधी CSRF क्षमताओं वास्तव में दो टोकन पर निर्भर करते हैं: एक एक गुप्त फ़ॉर्म तत्व है, और अन्य एक कुकी है। तो Html.AntiForgeryToken() सहायक केवल एक HTML स्निपेट वापस नहीं करता है। इसका यह कुकी सेट करने का दुष्प्रभाव भी है। ध्यान दें कि कुकी मान और फॉर्म मान बराबर नहीं हैं क्योंकि प्रत्येक जानकारी के विभिन्न टुकड़ों को एन्कोड करता है।

आप AntiForgery.GetTokens एपीआई का उपयोग करते हैं, इस विधि के बजाय एक HTML स्निपेट पैदा करने में कच्चे टोकन वापस आ जाएगी। इस विधि के लिए मानकों हैं:

  • oldCookieToken: अनुरोध पहले से ही एक विरोधी CSRF कुकी टोकन शामिल तो उसे यहां प्रदान करते हैं। यह पैरामीटर शून्य हो सकता है।
  • newCookieToken (बाहर पैरामीटर):तो oldCookieToken अशक्त था या एक वैध विरोधी CSRF कुकी टोकन का प्रतिनिधित्व नहीं किया था, इस पैरामीटर मान है कि आप प्रतिक्रिया कुकी में रखना चाहिए के साथ भरे जाएंगे। यदि oldCookieToken एक वैध विरोधी CSRF टोकन का प्रतिनिधित्व किया, तो newCookieToken अशक्त शामिल विधि रिटर्न, और तुम एक प्रतिक्रिया कुकी सेट करने की जरूरत नहीं है जब होगा।
  • फॉर्म टोकन (आउट पैरामीटर): यह पैरामीटर टोकन के साथ पॉप्युलेट किया जाएगा जो सर्वर पर वापस पोस्ट करते समय फॉर्म बॉडी में मौजूद होना चाहिए। यह वह मान है जो Html.AntiForgeryToken() पर कॉल में छुपा इनपुट तत्व द्वारा लपेटा जाता है।

आप इस एपीआई का उपयोग करते हैं मैन्युअल रूप से कुकी और फार्म टोकन उत्पन्न करने के लिए, आप टोकन मान्य करने के लिए में AntiForgery.Validate की the corresponding overload कॉल करने के लिए की आवश्यकता होगी।

+3

मैं sideeffect के बारे में पता है, लेकिन मेरे सवाल का किसी भी html रूप के बिना जटिल js आवेदन के बारे में है। मैं फॉर्म टोकन और कुकी टोकन प्राप्त करने के लिए AJAX अनुरोध भेज रहा हूं, उसके बाद, मैं सिर्फ फॉर्म टोकन के साथ अपना AJAX अनुरोध भेजता हूं। लेकिन अब मुझे कुकी सेट करने के लिए सुंदर और सरल तरीका नहीं पता है और HTML जंक पार्सिंग के बिना फॉर्म टोकन प्राप्त करें। –

+3

मैंने पाया कि 'एचटीएमएलहेल्पर' में जेनरेट किए गए एंटी जालसाजी फॉर्म टोकन के 'नाम' और 'वैल्यू 'को एक्सपोज़र फ्रेमवर्क जैसे जावास्क्रिप्ट में उपयोग करना आवश्यक है। मैं बस HTML तत्व नहीं लिख सकता, इसके बजाय मुझे ExtJs घटक का विस्तार करने और क्लाइंट साइड मॉडल से निपटने या मौजूदा छिपे हुए फ़ील्ड का उपयोग करने की आवश्यकता है, जिसे केवल पूरे इनपुट तत्व के बजाय नाम और मूल्य की आवश्यकता होती है ... 'AntiForgery.GetTokens': की आवश्यकता होती है कुकी के साथ खेलें; 'AntiForgery.Validate': पहले से ही आंतरिक रूप से' [ValidateAntiForgeryToken] 'विशेषता द्वारा बुलाया गया है ... मैं नाम और मूल्य प्राप्त करने के लिए OP HtmlHelper एक्सटेंशन का उपयोग करने के साथ समाप्त होता हूं। – CallMeLaNN

10

मुझे पता है इस सवाल पुराना है, लेकिन मैं यहाँ क्या पढ़ा के आधार पर मैं एक यथोचित सरल समाधान मेरे लिए काम करने लगता है कि के साथ आया था। मैं इसे एंगुलरजेएस एसपीए पर उपयोग कर रहा हूं जो आंशिक टेम्पलेट का उपयोग करता है, जिनमें से कुछ जिनमें पोस्ट सबमिशन शामिल हैं।

मैं दृश्य के शीर्ष पर इस कोड डाल:

@{ 
    string cookieToken, formToken; 
    string oldCookieToken = Request.Cookies[AntiForgeryConfig.CookieName] == null ? null : Request.Cookies[AntiForgeryConfig.CookieName].Value; 
AntiForgery.GetTokens(oldCookieToken, out cookieToken, out formToken); 

    if(oldCookieToken == null) 
    { 
     Request.Cookies.Add(new HttpCookie(AntiForgeryConfig.CookieName,  cookieToken)); 
    } 
    else 
    { 
     Request.Cookies[AntiForgeryConfig.CookieName].Value = cookieToken; 
    } 
} 

और फिर मैं जहाँ भी (एक ajax या AngularJS पोस्ट में जैसे,) प्रपत्र की antiforgery टोकन की आवश्यकता मैं बस शामिल हेडर में '@formToken' :

$http.post(route, JSON.stringify(args), { 
    headers: { 
     '@AntiForgeryConfig.CookieName': '@formToken', 
     'Content-Type': 'application/json; charset=utf-8', 
    }, 
}); 

ध्यान दें कि क्योंकि इस उदाहरण में मैं अपना कार्य विधि मैं भी हेडर के आधार पर विरोधी जालसाजी सत्यापन को लागू करने, खेतों फार्म नहीं था से वापस JSON डेटा की उम्मीद कर रहा हूँ। इस बारे में http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC. पर एक अच्छी पोस्ट है।यहाँ कार्यान्वयन है:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, 
       AllowMultiple = false, Inherited = true)] 
public sealed class ValidateJsonAntiForgeryTokenAttribute 
          : FilterAttribute, IAuthorizationFilter 
{ 
    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if(filterContext == null) 
     { 
      throw new ArgumentNullException("filterContext"); 
     } 

     var httpContext = filterContext.HttpContext; 
     var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; 
     AntiForgery.Validate(cookie != null ? cookie.Value : null, 
          httpContext.Request.Headers[AntiForgeryConfig.CookieName]); 
    } 
} 

और यहाँ उसके उपयोग के तरीके है:

[HttpPost] 
    [ValidateJsonAntiForgeryToken] 
    public JsonResult RecordVisit(VisitInfo info) 
संबंधित मुद्दे