2010-02-05 3 views
41

मुझे एएसपी.NET एमवीसी में एंटीफोर्गेरी टोकन के साथ समस्याएं आ रही हैं। अगर मैं अपने वेब सर्वर पर एक आईस्रेसेट करता हूं और उपयोगकर्ता अपने सत्र के साथ जारी रहता है तो उन्हें लॉगिन पेज पर बाउंस किया जाता है। भयानक नहीं है लेकिन फिर एंटीफोर्गेरी टोकन उड़ाता है और फिर से जाने का एकमात्र तरीका ब्राउज़र पर कुकी को उड़ाना है।मैं अपने एएसपी.NET एमवीसी ऐप में iisreset के बाद होने वाले एंटीफ़ोर्गेरी टोकन अपवाद को कैसे हल करूं?

संस्करण 1 के बीटा संस्करण के साथ यह मेरे लिए कुकी पढ़ने के दौरान गलत हो जाता था, इसलिए मैं सत्यापन टोकन मांगने से पहले इसे साफ़ करना चाहता था लेकिन इसे रिलीज़ होने पर तय किया गया था।

अब के लिए मुझे लगता है कि मैं बीटा समस्या को ठीक करने वाले मेरे कोड पर वापस रोल करूंगा लेकिन मैं मदद नहीं कर सकता लेकिन लगता है कि मुझे कुछ याद आ रहा है। क्या कोई आसान समाधान है, क्या मुझे बस अपना सहायक छोड़ना चाहिए और खरोंच से नया बनाना चाहिए? मुझे यह महसूस हो रहा है कि बहुत सी समस्या यह तथ्य है कि यह पुरानी एएसपी.Net पाइपलाइन में इतनी गहराई से बंधी हुई है और इसे ऐसा करने में मदद करने की कोशिश कर रही है जिसे वास्तव में करने के लिए तैयार नहीं किया गया था।

मुझे एएसपी.NET एमवीसी 2 आरसी के लिए स्रोत कोड में एक नज़र डाली गई थी और ऐसा लगता है कि कोड बहुत बदल गया है, जबकि मैंने कोशिश नहीं की है, मुझे नहीं लगता कि कोई जवाब है क्या आप वहां मौजूद हैं।

अपवाद के स्टैक ट्रेस का प्रासंगिक हिस्सा यहां दिया गया है।

संपादित करें: मुझे अभी एहसास हुआ कि मैंने उल्लेख नहीं किया है कि यह केवल GET अनुरोध पर टोकन डालने का प्रयास कर रहा है। यह वह सत्यापन नहीं है जो तब होता है जब आप पोस्ट को बंद कर देते हैं।

System.Web.Mvc.HttpAntiForgeryException: A required anti-forgery token was not 
supplied or was invalid. 
---> System.Web.HttpException: Validation of viewstate MAC failed. If this 
application is hosted by a Web Farm or cluster, ensure that <machineKey> 
configuration specifies the same validationKey and validation algorithm. 
AutoGenerate cannot be used in a cluster. 
---> System.Web.UI.ViewStateException: Invalid viewstate. 
    Client IP: 127.0.0.1 
    Port: 4991 
    User-Agent: scrubbed 
    ViewState: scrubbed 
    Referer: blah 
    Path: /oursite/Account/Login 
---> System.Security.Cryptography.CryptographicException: Padding is invalid and 
cannot be removed. 
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast) 
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) 
at System.Security.Cryptography.CryptoStream.FlushFinalBlock() 
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo) 
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) 
--- End of inner exception stack trace --- 
--- End of inner exception stack trace --- 
at System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) 
at System.Web.UI.ViewStateException.ThrowMacValidationError(Exception inner, String persistedState) 
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) 
at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) 
at System.Web.Mvc.AntiForgeryDataSerializer.Deserialize(String serializedToken) 
--- End of inner exception stack trace --- 
at System.Web.Mvc.AntiForgeryDataSerializer.Deserialize(String serializedToken) 
at System.Web.Mvc.HtmlHelper.GetAntiForgeryTokenAndSetCookie(String salt, String domain, String path) 
at System.Web.Mvc.HtmlHelper.AntiForgeryToken(String salt, String domain, String path) 
+2

देखें में भी जोड़ सकते हैं: http://stackoverflow.com/quest आयनों/1360078/एएसपी निवल MVC-मान्यता के- viewstate-मैक-विफल रहा है – Shog9

उत्तर

40

अपने MachineKey AutoGenerate, तो अपने सत्यापन टोकन, इत्यादि पर सेट है एक आवेदन को पुनः आरंभ करने से बच नहीं होगा - जब यह शुरू होता है ASP.NET एक नई कुंजी बना, और फिर करने के लिए सक्षम नहीं होगा टोकन सही ढंग से डिक्रिप्ट करें।

आप इस एक बहुत देख रहे हैं, मैं सुझाव चाहते हैं:

  1. एक स्थिर MachineKey का विन्यास में अधिक जानकारी के
  2. कोशिश के लिए "How to: Configure a MachineKey" देखते हैं (आप आवेदन स्तर पर ऐसा करने में सक्षम होना चाहिए), एक loadbalanced आवेदन है, जो डब्ल्यू होने से जब साइट

सबसे अच्छा तरीका इस्तेमाल किया जा रहा है यह है क्या करने के लिए आईआईएस पुनः निर्धारित करता है प्रदर्शन करने के लिए नहीं बीमार आपको एक स्थिर मशीनकी सेट करने की आवश्यकता है। कम से कम उन कोई बात बिगड़ जाए की उम्मीद होगी - एक अन्य विकल्प साइट के रूट में app_offline.htm नाम की एक फ़ाइल है, जो साइट ऑफ़लाइन अपने संदेश लेने के लिए और प्रदर्शित करेगा डाल कर साइट नीचे ले रहा है।

public ActionResult LogOn() 
    { 
     formsAuthentication.SignOut(); 

     Response.Cookies.Clear(); 

     Session[SessionKeys.USER_SESSION_KEY] = null; 
     Session.Clear(); 
     Session.Abandon(); 


     return View(); 
    } 

महत्वपूर्ण हिस्सा था:

+0

आह, यह समस्या भी हो सकती है। मैं इसे आज़मा दूंगा और मानता हूं कि यह काम करता है, मैं इसे उत्तर के रूप में चिह्नित करूंगा। Iisresets नहीं करना एक अच्छा विचार है, लेकिन मैं यह सुनिश्चित करने की कोशिश कर रहा हूं कि यह असली दुनिया में यथासंभव विश्वसनीय रूप से काम करता है। –

+3

यहाँ इस विषय पर कुछ बहुत अच्छा लेख हैं http://adam.kahtava.com/journal/2009/11/23/how-to-fix-the-validation-of-viewstate-mac-failed-error- एस्पनेट-एमवीसी/ http: //adam.kahtava।com/पत्रिका/2009/11/25/क्या-हैं-विरोधी क्रॉस साइट अनुरोध-जालसाजी-टोकन और क्या-हैं-वे-अच्छे के लिए/ – superlogical

+9

मैं उचित मशीन कुंजी है, लेकिन कभी कभी मुझे मिल गया है HttpAntiForgeryException। :(मैं क्यों नहीं पता है:।। मशीन कुंजियों के बारे में/ – dariol

4

अगर मैं अपने वेब सर्वर पर एक iisreset करते हैं और यदि कोई उपयोगकर्ता अपने सत्र वे एक लॉगिन पृष्ठ पर बाउंस हो साथ जारी है।

कोई कारण एक iisreset प्रवेश पृष्ठ पर उपयोगकर्ता लाने के लिए है। यदि आप प्रमाणीकरण जानकारी ट्रैक करने के लिए कुकीज़ का उपयोग करते हैं और एक स्टेटलेस एप्लिकेशन है, तो उपयोगकर्ता को सर्वर रीबूट करने के बाद भी प्रमाणित रहना चाहिए (बेशक अगर रीसेट के दौरान अनुरोध किया जाता है तो यह असफल हो जाएगा)।

+1

कि तकनीकी रूप से सच है और कुछ मैं वास्तव में हल करने के लिए चाहिए, लेकिन यह एक अलग मुद्दा है। तथ्य यह है कि जब मैं पेज पर टोकन डालने का प्रयास करता हूं तो मुझे अपवाद मिलता है। –

+1

@Darin - लगातार लॉगिन और विरोधी जालसाजी तंत्र '' मूल्यों IISResets भर में लगातार किया जा रहा है पर निर्भर कर रहे हैं। यदि वे स्वत: उत्पन्न करने के लिए सेट हैं तो कुंजी बदल जाती हैं और कुकी अब मान्य नहीं होगी। – Kev

+0

हां, इससे साझा होस्टिंग वातावरण में महत्वपूर्ण समस्याएं होती हैं जो संतुलित रूप से संतुलित होती हैं। हालांकि, मैंने "मुझे लॉग इन रखें" समस्या का हल ढूंढ लिया, और यह ''machineKey' को मेरे 'Web.config' में रखना था - यह अच्छी तरह से तय किया गया था। –

13

अभी के लिए मैं एक ऐसे समाधान के साथ गया हूं जो अपवाद फेंक दिया गया है तो कुकी को स्क्रब्स करता है। अगर अपवाद फिर से फेंक दिया जाता है तो मैं इसे ऐसा होने दूंगा।

मैं इस आशा के लिए अब 'उत्तर' के रूप में चिह्नित नहीं करूंगा कि किसी के पास बेहतर जवाब है।

public static class MyAntiForgeryExtensions 
{ 
    // Methods 
    public static string MyAntiForgeryToken(this HtmlHelper helper) 
    { 
     return MyAntiForgeryToken(helper, null); 
    } 

    public static string MyAntiForgeryToken(this HtmlHelper helper, string salt) 
    { 
     string fragment; 
     string path = helper.ViewContext.HttpContext.Request.ApplicationPath; 
     try 
     { 
      fragment = helper.AntiForgeryToken(salt, null, path); 
     } 
     catch (HttpAntiForgeryException) 
     { 
      // okay, scrub the cookie and have another go. 
      string cookieName = GetAntiForgeryTokenName(path); 
      helper.ViewContext.HttpContext.Request.Cookies.Remove(cookieName); 
      fragment = helper.AntiForgeryToken(salt, null, path); 
     } 
     return fragment; 
    } 

    #region AntiForgeryData code that shouldn't be sealed 
    // Copied from AntiForgeryData since they aren't accessible. 
    internal static string GetAntiForgeryTokenName(string appPath) { 
     if (String.IsNullOrEmpty(appPath)) { 
      return "__RequestVerificationToken"; 
     } 
     else { 
      return "__RequestVerificationToken_" + Base64EncodeForCookieName(appPath); 
     } 
    } 
    private static string Base64EncodeForCookieName(string s) { 
     byte[] rawBytes = Encoding.UTF8.GetBytes(s); 
     string base64String = Convert.ToBase64String(rawBytes); 

     // replace base64-specific characters with characters that are safe for a cookie name 
     return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_'); 
    } 
    #endregion 
} 
+0

मैंने वही किया। मुझे लगता है कि यह 'एंटीफोर्गेरी टोकन' विधि के साथ एक बड़ा डिज़ाइन दोष है, और आपकी टिप्पणियों के मुताबिक, यह और भी निराशाजनक है कि एमवीसी कोड आंतरिक/मुहरबंद है, क्योंकि यह हमें आसानी से इसे ठीक करने से रोकता है! –

+0

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

+0

एक बात मैं MVC3 समर्थन के लिए बदल जाएगा कि आपके स्थिर सहायक विस्तार तरीकों MvcHtmlString लौटना चाहिए, क्योंकि helper.AntiForgeryToken (स्ट्रिंग, स्ट्रिंग, स्ट्रिंग) एक सादे स्ट्रिंग के बजाय उस प्रकार रिटर्न है। –

4

वास्तव में मैं यह मेरा लॉगऑन कार्रवाई में काम करने के लिए मिल गया) Response.Cookies.Clear (;

+0

कि आधा काम करता है Zaph के दृष्टिकोण बेहतर काम करता है, हालांकि, क्योंकि यह आप iisreset के बाद प्रवेश पृष्ठ पर बाउंस हो रही यह भी वजह से एक की अवैध बनने से रोकता है कुकी से बचाता है। iisreset। –

+2

मैं भी में लॉग इन करने जब पहले से लॉग इन उपयोगकर्ता लॉग आउट द्वारा दंडित नहीं किया जाना चाहिए की कोशिश कर रहा एक स्थिर मशीन कुंजी है, लेकिन एक ही समस्या हो रही थी। – Jeff

+1

। मामले में उपयोगकर्ता अनजाने में खुले कई खिड़कियां है और गलती से एक पर काम करता है बासी प्रवेश पृष्ठ, उपयोगकर्ता यहां अन्य विंडो में काम/राज्य खोने। एक बेहतर समाधान जोखिम उन्हें लॉगिन स्क्रीन पर अग्रेषित करने के लिए, की तरह [जिया उन्हें एक antiforgery पेज पर अग्रेषित किया] (http://stackoverflow.com/a/ है 32624782/235908)। –

10

मैं इस मुद्दे को और आप अपने वेब-config में स्पष्ट मशीन कुंजी जोड़ते है क्या करने की जरूरत ठीक करने के लिए ...

<machineKey validationKey="D82960E6B6E9B9029D4CAB2F597B5B4AF631E3C182670855D25FBDE1BFAFE19EFDE92ABBD1020FC1B2AE455D5B5F8D094325597CE1A7F8B15173407199C85A16" decryptionKey="577404C3A13F154908D7A5649EEC8D7C8A92C35A25A3EC078B426BB09D426A71" validation="SHA1" decryption="AES" /> 

सुनिश्चित था अपने web.config में रखा भीतर ...

<system.web> 
+1

को देखते हुए लिंक काम कर रहा है नहीं। कृपया URL नीचे का उपयोग [http://www.allkeysgenerator.com/Random/ASP-Net-MachineKey-Generator.aspx] – Optimus

+1

मैं पागल हो सकता है, लेकिन मैं होता नहीं मेरे लिए मेरी चाबियाँ उत्पन्न करने के लिए किसी भी इंटरनेट वेबसाइट का उपयोग नहीं करें। आईआईएस के बाद के संस्करण इसे कर सकते हैं, और आप इसे .NET सिस्टम क्लास 'RNGCryptoServiceProvider' का उपयोग करके भी कर सकते हैं। – Menahem

+0

आप पागल हो सकते हैं लेकिन आप भी सही हैं। –

7

आप AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;global.asax

protected void Application_Start() { 
    AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; 
} 
+1

वह क्या करता है, बिल्कुल? http://www.asp.net/mvc/overview/security/xsrfcsrf-prevention-in-aspnet-mvc-and-web-pages से –

+0

@TimothyGroote: "एक बूलियन तय है कि चाहे विरोधी XSRF प्रणाली को निष्क्रिय करना चाहिए दावा-आधारित पहचानों के लिए इसका समर्थन। यदि यह मान सत्य है, तो सिस्टम यह मान लेगा कि IIDentity.Name एक अद्वितीय प्रति-उपयोगकर्ता पहचानकर्ता के रूप में उपयोग के लिए उपयुक्त है और वाई-फाई में वर्णित विशेष-मामले आईसीएमएलएस इडेंटिटी या क्लक्लेम्स इडेंटिटी की कोशिश नहीं करेगा। एसीएस/दावा-आधारित प्रमाणीकरण खंड। डिफ़ॉल्ट मान गलत है। " यह IIdentity.Name को सुरक्षित होने के लिए पर्याप्त अद्वितीय पहचानकर्ता होने की आवश्यकता है। –

संबंधित मुद्दे