2012-01-26 13 views
7

में AuthorizeAttribute में मॉडल डेटा प्राप्त करना मैं अपने नियंत्रक कार्यों को AuthorizeAttribute के साथ सजा रहा हूं।एमवीसी 3

[ServiceAuthorize(Roles="Editor,Publisher,Administrator")] 
public JsonResult Create(NewsArticle newsArticle) 

मेरी NewsArticle मॉडल में एक क्षेत्र है कि मैं अपने AuthorizeAttribute में OnAuthorize विधि में उपयोग करना चाहते हैं नहीं है।

क्या AuthorizeAttribute की ऑनअधिकृत विधि के भीतर से मॉडल पर जाने का कोई तरीका है?

मुझे लगता है कि यह कहीं भी AuthorizationContext के भीतर उपलब्ध होगा लेकिन मुझे यह नहीं मिल रहा है। मुझे पता है कि मैं इसे फ़िल्टर विशेषता के ActionExecutingContext में प्राप्त कर सकता हूं लेकिन इसका मतलब है कि मुझे अपनी कार्रवाई पर एक और फ़िल्टर की आवश्यकता होगी और मैं एक ही चरण में सभी प्राधिकरण निष्पादित करने में सक्षम होना चाहता हूं।

धन्यवाद।

उत्तर

6

क्या प्राधिकरण एट्रिब्यूट की ऑनअधिकृत विधि के भीतर से मॉडल पर जाने का कोई तरीका है?

नहीं क्योंकि OnAuthorization मॉडल बांधने की मशीन से पहले चलाता है। क्या तुम कर सकते हो मूल्य प्रदाता से मूल्य को पढ़ने के लिए है:

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var value = filterContext.Controller.ValueProvider.GetValue("someproperty"); 
    ... 
} 
+0

धन्यवाद डारिन। मुझे लगता है कि "कुछ प्रॉपर्टी" शायद मेरे मामले में "न्यूज़ आर्टिकल" होगा? मैं उसे देखूंगा। – Perry

+1

@ पेरी, नहीं, आप गलत मानते हैं। यह आपकी 'न्यूज़ आर्टिकल' कक्षा पर एक संपत्ति होगी जिसमें आप रुचि रखते हैं। जैसा कि मैंने कहा था, चूंकि 'ऑन-प्राधिकरण' विधि मॉडल बाइंडर से पहले चलती है, इसलिए आप इस चरण में 'न्यूज़ आर्टिकल' के उदाहरण के बारे में वास्तव में बात नहीं कर सकते हैं। आप अनुरोध मानों को देख सकते हैं जो वैल्यूप्रोवाइडर करता है। बेशक वे इस चरण में तारों के रूप में होंगे। आपको कुछ अतिरिक्त पार्सिंग भी करने की आवश्यकता हो सकती है। स्पष्टीकरण के लिए –

+0

धन्यवाद। – Perry

1

मैं, मूल रूप से कार्रवाई विधि मानकों के आधार पर विशेषताओं के साथ प्राधिकरण को नियंत्रित करने के लिए इच्छुक, एक उदाहरण के रूप में एक ही कार्य को पूरा करने की कोशिश कर रहा था:

[MyAuthorize] 
public ActionResult MyAction(
[Require(Permission.Write)] MyCustomObject arg1, 
[Require(Permission.Read)] MyCustomObject arg2 
) { 
    // ... all authorization would be handled before the action is invoked ... 
} 

class MyAuthorize : AuthorizeAttribute { 
    public override void OnAuthorization(AuthorizationContext filterContext) { 
     // ... filterContext doesn't have the argument objects ... 
    } 
} 

मैं उसी समस्या में भाग गया, जब AuthorzeAttribute.OnAuthorization(...) ओवरराइड करते हुए मॉडल बाध्य तर्क अभी तक मौजूद नहीं हैं। मुझे जो चाहिए वह पूरा करने के लिए, मैंने IActionFilter लागू किया जो एक विधि OnActionExecuting का खुलासा करता है जिसे मॉडल बाध्य होने के बाद बुलाया जाएगा लेकिन कार्रवाई लागू होने से पहले। मेरे प्रोटोटाइप कार्यान्वयन इस तरह दिखता है:

class MyAuthorizeAttribute : AuthorizeAttribute, IActionFilter { 

    public override void OnAuthorization(AuthorizationContext filterContext) { 
     // ... I guesss this isn't really needed any more. 
     // the auth check is handled in OnActionExecuting. 
    } 

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { 

    } 

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { 

     foreach (var param in filterContext.ActionDescriptor.GetParameters()) { 
      var attr = (RequireAttribute)param.GetCustomAttributes(typeof(RequireAttribute), false).FirstOrDefault(); 
      if(attr != null) { 
       Object obj; 
       if (filterContext.ActionParameters.TryGetValue(param.ParameterName, out obj)) { 
        var sec = obj as ISecurable; 
        if (sec == null || !sec.HasPermission(filterContext.RequestContext, attr.Permission)) { 
         filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Unauthorized);         
        } 
       } 
      } 
     } 
    } 
} 

interface ISecurable { 
    bool HasPermission(Permission permission); 
} 

यह सिर्फ एक परियोजना मैं पर काम कर रहा हूँ के लिए अवधारणा का एक सबूत है, लेकिन यह समस्या का समाधान की तरह लगता है।