2012-10-19 11 views
32

यहाँ में HttpAntiForgeryException निपटने का एक तरीका परिदृश्य है। फिर उपयोगकर्ता ब्राउजर बैक बटन का उपयोग कर रहा है, और अब वह लॉगिन पेज पर है। वह फिर से प्रवेश करने की कोशिश करता है, लेकिन अब एक अपवाद फेंका जाता है:ठीक से MVC 4 आवेदन

HttpAntiForgeryException (0x80004005): प्रदान की विरोधी जालसाजी टोकन उपयोगकर्ता के लिए "मतलब था", लेकिन वर्तमान उपयोगकर्ता है "उपयोगकर्ता नाम"।

मुझे पता है कि यह कैशिंग से संबंधित है। कस्टम NoCache फिल्टर है जो सभी आवश्यक शीर्षकों के सेट का उपयोग कर लॉगिन कार्रवाई के लिए मैं विकलांग ब्राउज़र कैशिंग - नहीं-कैश, कोई दुकान, चाहिए-पुनः सत्यापित, आदि लेकिन

  • इस सभी ब्राउज़रों पर काम नहीं कर रहा
  • विशेष रूप से सफारी (ज्यादातर मामलों में मोबाइल) कुल सेटिंग्स को अनदेखा करता है

मैं हैक बनाने और सफारी मोबाइल को ताज़ा करने के लिए मजबूर करने की कोशिश करूंगा, लेकिन यह मेरी अपेक्षा नहीं है।

मैं अगर मैं कर सकते हैं जानना चाहूंगा:

  • किसी भी समस्या मौजूद है उपयोगकर्ता (पूरी तरह से उपयोगकर्ता के लिए पारदर्शी)
  • विरोधी जालसाजी टोकन उपयोगकर्ता नाम बदल कर भी इस समस्या को रोकने के बिना दिखाए संभाल अपवाद जो होगा इस अपवाद के बिना उपयोगकर्ता लॉगिन को फिर से अनुमति दें, यदि ब्राउज़र कैशिंग से संबंधित मेरे हैक ब्राउज़र के अगले संस्करणों में काम करना बंद कर देंगे।
  • मैं वास्तव में ब्राउज़र व्यवहार पर भरोसा नहीं करना चाहता, क्योंकि प्रत्येक व्यक्ति अलग-अलग व्यवहार करता है।

UPDATE 1

कुछ स्पष्टीकरण बनाने के लिए, मुझे पता है कि MVC में त्रुटियों को संभालने के लिए। समस्या यह है कि यह हैंडलिंग त्रुटियां मेरी समस्या को हल नहीं कर रही हैं। त्रुटि प्रबंधन का मूल विचार अच्छा संदेश के साथ कस्टम त्रुटि पृष्ठ पर रीडायरेक्ट किया गया है। लेकिन मैं इस त्रुटि को रोकने के लिए, उपयोगकर्ता दृश्यमान तरीके से इसे संभालने के लिए नहीं रोकना चाहता हूं। हैंडल द्वारा मेरा मतलब है कि उपयोगकर्ता नाम बदलें या अन्य उपयुक्त कार्रवाई करें, फिर लॉगिन जारी रखें।

अद्यतन 2

मैं समाधान जो मेरे लिए काम कर रहा है नीचे जोड़ दिया है।

उत्तर

16

जांच के कुछ समय बाद मुझे लगता है कि मुझे उपयोगकर्ता के लिए इस त्रुटि से छुटकारा पाने का कोई तरीका मिला है। यह सही नहीं है, लेकिन कम से कम त्रुटि पृष्ठ प्रदर्शित नहीं:

मैं HandleErrorAttribute के आधार पर फिल्टर निर्मित:

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", 
     Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")] 
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
    public class LoginAntiforgeryHandleErrorAttribute : FilterAttribute, IExceptionFilter 
    { 
     #region Implemented Interfaces 

     #region IExceptionFilter 

     /// <summary> 
     /// </summary> 
     /// <param name="filterContext"> 
     /// The filter context. 
     /// </param> 
     /// <exception cref="ArgumentNullException"> 
     /// </exception> 
     public virtual void OnException(ExceptionContext filterContext) 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      if (filterContext.IsChildAction) 
      { 
       return; 
      } 

      // If custom errors are disabled, we need to let the normal ASP.NET exception handler 
      // execute so that the user can see useful debugging information. 
      if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) 
      { 
       return; 
      } 

      Exception exception = filterContext.Exception; 

      // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method), 
      // ignore it. 
      if (new HttpException(null, exception).GetHttpCode() != 500) 
      { 
       return; 
      } 

      // check if antiforgery 
      if (!(exception is HttpAntiForgeryException)) 
      { 
       return; 
      } 

      filterContext.Result = new RedirectToRouteResult(
       new RouteValueDictionary 
       { 
        { "action", "Index" }, 
        { "controller", "Home" } 
       }); 

      filterContext.ExceptionHandled = true; 
     } 

     #endregion 

     #endregion 
    } 

तब मैं इस फ़िल्टर लागू पोस्ट कार्रवाई लॉगिन करने के लिए:

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
[LoginAntiforgeryHandleError] 
public ActionResult Login(Login model, string returnUrl) 
{ 

मुख्य विचार इस समाधान का मुख्य सूचकांक कार्रवाई के लिए विरोधी जालसाजी अपवाद को पुनर्निर्देशित करना है। यदि उपयोगकर्ता को अभी भी अनधिकृत नहीं किया जाएगा तो यह लॉगिन पृष्ठ दिखाएगा यदि उपयोगकर्ता पहले ही प्रमाणीकृत होगा तो यह अनुक्रमणिका पृष्ठ दिखाएगा।

अद्यतन 1 इस समाधान के साथ एक संभावित समस्या है। अगर कोई अलग-अलग प्रमाण-पत्रों के साथ लॉग इन कर रहा है तो त्रुटि पर इसे अतिरिक्त लॉगिन रनटाइम जोड़ा जाना चाहिए - पिछले उपयोगकर्ता को लॉगआउट करना और नया लॉगिन करना चाहिए। इस परिदृश्य को संभाला नहीं जाता है।

+0

यह मेरे लिए बहुत अच्छा काम करता है। मुझे किसी भी फैंसी करने की ज़रूरत नहीं है। बस पीले रंग की स्क्रीन फेंक नहीं। – hal9000

5

आपको अपनी त्रुटि को संभालने के लिए एक एक्शन फ़िल्टर जोड़कर अपवाद को संभालने में सक्षम होना चाहिए।

[HandleError(View="AntiForgeryExceptionView", ExceptionType = typeof(HttpAntiForgeryException))] 

टोडो तो सुनिश्चित करें कि आपके web.config में कस्टम त्रुटियां चालू हैं।

<customErrors mode="On"/> 

आप हैंडल त्रुटि के बारे में अधिक जानकारी के लिए इस blog पर भी एक नज़र डाल सकते हैं।

संपादित आप MVC4 उपयोग कर रहे हैं और ब्लॉग MVC3 के बारे में आप भी MSDN library - HandleErrorAttribute पर एक नज़र डालें सकता है, लेकिन संस्करण वास्तव में एक फर्क नहीं करना चाहिए है के बाद से।

+0

हाँ, लेकिन यह सब redirectling (तो यह त्रुटियों से निपटने के बारे में बता रहा है वर्तमान कार्रवाई (निष्पादन टूट जाता है) मैं तोड़ने के बिना इस त्रुटि को संभालने के लिए चाहते हैं। कार्रवाई, इसलिए इस मामले में हैंडल करें, उपयोगकर्ता नाम को प्रतिस्थापित करें और उचित डेटा के साथ लॉगिन जारी रखें – Marcin

+0

मुझे लगता है कि जब आप ca n त्रुटि को पकड़ें जिसे आप इसे एक दृश्य (नियंत्रक) पर रीडायरेक्ट कर सकते हैं जहां आप उपयोगकर्ता नाम को प्रतिस्थापित करते हैं और पहले दर्ज डेटा के साथ लॉगिन जारी रखते हैं। यह भी देखें: http://stackoverflow.com/questions/1794936/how-do-i-pass-viewdata-to-a-handleerror-view –

15

यदि आपके पास केवल एक या कुछ फ़ंक्शन प्रभावित हैं, तो फ़िल्टर बनाना थोड़ा तकनीकी ओवरकिल हो सकता है। एक सरल लेकिन गैर सामान्य समाधान एक पुरानी सवाल बस विशेष विधि के लिए [ValidateAntiForgeryToken] को हटा दें और यदि उपयोगकर्ता के प्रवेश की जाँच के बाद एक मैनुअल सत्यापन जोड़ना है

if (User.Identity.IsAuthenticated) 
{ 
    return RedirectToAction("Index", "Home"); 
} 
System.Web.Helpers.AntiForgery.Validate(); 
/* proceed with authentication here */ 
+0

धन्यवाद, यह बहुत अच्छा काम करता प्रतीत होता है और फिर भी वही सुरक्षा प्रदान करता है। –

+0

यह मेरे साथ काम नहीं करता है, यह बिल्कुल वही त्रुटि देता है लेकिन इस लाइन पर: System.Web.Helpers.AntiForgery.Validate(); –

1

-। लेकिन मैं आज इस समस्या में पड़ गए, और जिस तरह से मैं इसे हल तो जैसे logoff कार्रवाई के लिए पुनः निर्देशित द्वारा किया गया था:

public ActionResult Login(string returnUrl) 
{ 
    if (WebSecurity.IsAuthenticated) 
     return RedirectToAction("LogOff"); 

    ... 
}