2009-12-21 4 views
15

क्या प्रवर्तन को केंद्रीकृत करने का कोई तरीका है कि प्रत्येक एक्शन विधि में "ValidateAntiForgeryToken" विशेषता होनी चाहिए? मुझे लगता है कि इसे "रूटिंग" कक्षाओं को विस्तारित करके किया जाना होगा।सुनिश्चित करें कि प्रत्येक नियंत्रक विधि में ValidateAntiForgery टोकन विशेषता है?

संपादित करें: या शायद एप्लिकेशन स्टार्टअप पर कुछ प्रतिबिंब करें?

उत्तर

22

हां। आप अपना खुद का बेसकंट्रोलर बनाकर ऐसा कर सकते हैं जो एमवीसी नियंत्रक को विरासत में लेता है, और ऑन-प्राधिकरण() को ओवरलोड करता है। आप इसे लागू करने से पहले इसे एक पोस्ट घटना है यह सुनिश्चित करना चाहते:

public abstract class MyBaseController : Controller 
{ 
    protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
    //enforce anti-forgery stuff for HttpVerbs.Post 
    if (String.Compare(filterContext.HttpContext.Request.HttpMethod, 
      System.Net.WebRequestMethods.Http.Post, true) == 0) 
    { 
     var forgery = new ValidateAntiForgeryTokenAttribute(); 
     forgery.OnAuthorization(filterContext); 
    } 
    base.OnAuthorization(filterContext); 
    } 
} 

एक बार जब आप है, सुनिश्चित करें कि आपके नियंत्रकों के सभी इस MyBaseController (या जो भी आप इसे कहते हैं) से विरासत हैं। या यदि आप एक ही कोड के साथ पसंद करते हैं तो आप इसे प्रत्येक नियंत्रक पर कर सकते हैं।

+1

यह समाधान एमवीसी 2 पर काम नहीं करने के लिए seams। यह एमवीसी 1 के लिए ठीक काम कर रहा है, लेकिन जैसे ही हमने v2 में अपग्रेड किया, यह काम करना बंद कर दिया।अब समाधान खोजने की कोशिश कर रहा है। –

+0

इसे मेरे ध्यान में लाने के लिए धन्यवाद। मैं भी देखूँगा। – eduncan911

+1

मुझे कम से कम _a_ समाधान मिला, शायद सबसे अच्छा नहीं। नीचे मेरा जवाब देखें। टिप्पणी बॉक्स कोड स्वरूपण के साथ बहुत अच्छा नहीं था =) –

8

लगता है जैसे आप "ओप्स मैं इसे सेट करना भूल गए" को रोकने की कोशिश कर रहे हैं। यदि ऐसा है तो मुझे लगता है कि ऐसा करने के लिए सबसे अच्छी जगह कस्टम नियंत्रकActionInvoker के साथ है। , अधिमानतः अपने आधार नियंत्रक

public class MustHaveAntiForgeryActionInvoker : ControllerActionInvoker 
{ 
    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) 
    { 
     var foundAction = base.FindAction(controllerContext, controllerDescriptor, actionName); 

     if(foundAction.GetCustomAttributes(typeof(ValidateAntiForgeryTokenAttribute), true).Length == 0) 
      throw new InvalidOperationException("Can't find a secure action method to execute"); 

     return foundAction; 
    } 
} 
फिर अपने नियंत्रक में

:

ActionInvoker = new MustHaveAntiForgeryActionInvoker(); 

बस चाहता था

अनिवार्य रूप से आप क्या करना चाहते हैं यह भी एक AntiForgery टोकन के बिना एक कार्रवाई खोजने से MVC रोक है उस कस्टम कंट्रोलर बेस क्लास को "मोटी" और आईएमओ को एमवीसी के शानदार एक्स्टेंसिबिलिटी पॉइंट्स का उपयोग करने के लिए हमेशा सर्वोत्तम अभ्यास करना पड़ता है, जिनकी आपको आवश्यकता होती है।

यहाँ MVC के तानाना अंक से ज्यादातर का एक अच्छा गाइड है: http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx

7

ठीक है, मैं सिर्फ MVC v2.0 के लिए एक परियोजना अपग्रेड किया गया है, और eduncan911 के समाधान अब और काम नहीं करता है अगर आप AuthorizeAttribute पर उपयोग आपके नियंत्रक कार्यों। यह समझना मुश्किल था कि क्यों।

तो, कहानी में अपराधी यह है कि एमवीसी टीम ने के मूल्य में ViewContext.HttpContext.User.Identity.Name संपत्ति का उपयोग जोड़ा।

बेस नियंत्रक में ओवरराइड OnAuthorization नियंत्रक कार्रवाई पर किसी भी फ़िल्टर से पहले निष्पादित किया जाता है। इसलिए, समस्या यह है कि प्राधिकरण विशेषता अभी तक लागू नहीं हुई है और इसलिए ViewContext.HttpContext.User सेट नहीं है। तो UserName स्ट्रिंग है। लक्षण जबकि एंटीफ़ोर्गेरी टोकन सत्यापन के लिए उपयोग किया जाता है, वास्तविक उपयोगकर्ता नाम = असफल होता है।

हम इसे अब हल इस कोड के साथ:

public abstract class MyBaseController : Controller 
{ 
    protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     //enforce anti-forgery stuff for HttpVerbs.Post 
     if (String.Compare(filterContext.HttpContext.Request.HttpMethod, "post", true) == 0) 
     { 
      var authorize = new AuthorizeAttribute(); 
      authorize.OnAuthorization(filterContext); 
      if (filterContext.Result != null) // Short circuit validation 
       return; 
      var forgery = new ValidateAntiForgeryTokenAttribute(); 
      forgery.OnAuthorization(filterContext); 
     } 
     base.OnAuthorization(filterContext); 
    } 
} 

MVC कोड आधार के लिए कुछ संदर्भों:

ControllerActionInvoker#InvokeAuthorizationFilters() लाइन 283. एक ही लघु सर्किटिंग। AntiForgeryData#GetUsername() लाइन 98. नई कार्यक्षमता।

+0

मैं आगे बढ़ गया और y upvotes (+3, वाह!) दिया। लेकिन, मैं 3.5 फ्रेमवर्क पर वीएस -2010 आरटीएम के साथ एमवीसी 2.0 आरटीएम का उपयोग कर रहा हूं (यह एक एज़ूर प्रोजेक्ट है, इसलिए मुझे अभी 3.5 रहना चाहिए)। पोस्ट किया गया विरोधी जालसाजी समाधान अभी भी काम करता है। मुझे आश्चर्य है कि क्या मुद्दा यह था कि आप एमवीसी 2.0 आरसी 2 या समान रूप से उपयोग कर रहे थे? – eduncan911

0

इस बारे में कैसे?

[ValidateAntiForgeryToken] 
public class MyBaseController : Controller 
{ 
} 
संबंधित मुद्दे