2012-06-14 6 views
16

मैं एक नियंत्रक विधि Edit जिसमें उपयोगकर्ता डेटा संपादित कर सकते हैं वे इतनी तरह बनाया था बुलाया है ...ASP.NET MVC केवल यह बताने के लिए उपयोगकर्ता संपादित उसका/उसकी खुद की सामग्री

public ActionResult Edit(int id) 
{ 
    Submission submission = unit.SubmissionRepository.GetByID(id); 
    User user = unit.UserRepository.GetByUsername(User.Identity.Name); 

    //Make sure the submission belongs to the user 
    if (submission.UserID != user.UserID) 
    { 
     throw new SecurityException("Unauthorized access!"); 
    } 

    //Carry out method 
} 

इस विधि काम करता है गुण ठीक है हालांकि यह प्रत्येक नियंत्रक संपादन विधि में डालने के लिए थोड़ा गन्दा है। प्रत्येक तालिका में हमेशा UserID होता है, इसलिए मैं सोच रहा था कि कोड क्लीनर बनाने के लिए [Authorize] विशेषता या कुछ अन्य तंत्र के माध्यम से इसे स्वचालित करने का कोई आसान तरीका था या नहीं।

उत्तर

24

हाँ, आप एक कस्टम के माध्यम से विशेषता अधिकृत करें कि लक्ष्य को हासिल कर सकते हैं:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 

     var rd = httpContext.Request.RequestContext.RouteData; 

     var id = rd.Values["id"]; 
     var userName = httpContext.User.Identity.Name; 

     Submission submission = unit.SubmissionRepository.GetByID(id); 
     User user = unit.UserRepository.GetByUsername(userName); 

     return submission.UserID == user.UserID; 
    } 
} 

और उसके बाद:

[MyAuthorize] 
public ActionResult Edit(int id) 
{ 
    // Carry out method 
} 

और मान लें कि आप इस प्रस्तुत उदाहरण है कि हम कस्टम में दिलवाया को खिलाने के लिए की आवश्यकता है डेटाबेस को मारने से बचने के लिए एक्शन पैरामीटर के रूप में विशेषता एक बार फिर आप निम्न कार्य कर सकते हैं:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 

     var rd = httpContext.Request.RequestContext.RouteData; 

     var id = rd.Values["id"]; 
     var userName = httpContext.User.Identity.Name; 

     Submission submission = unit.SubmissionRepository.GetByID(id); 
     User user = unit.UserRepository.GetByUsername(userName); 

     rd.Values["model"] = submission; 

     return submission.UserID == user.UserID; 
    } 
} 

और उसके बाद:

[MyAuthorize] 
public ActionResult Edit(Submission model) 
{ 
    // Carry out method 
} 
+1

धन्यवाद व्यवस्थापक उपयोगकर्ताओं की तरह कुछ अनुमति देने के लिए बाद में लचीलापन होता है करने की अनुमति होगी! मैं इसे और अधिक सामान्य बनाने जा रहा हूं। जैसा कि IUserOwnable नामक एक इंटरफ़ेस को प्रस्तुत करना है जिसमें उपयोगकर्ता आईडी है। और उसके बाद उस संग्रह में संग्रह को पास करें जहां यह IUserOwnable लाता है और उपयोगकर्ता के उपयोगकर्ता आईडी को IUserOwnable –

+0

के उपयोगकर्ता आईडी से तुलना करता है, निश्चित रूप से, यह सामान्य के रूप में बनाया जा सकता है क्योंकि आप अपनी विशिष्ट आवश्यकताओं के अनुरूप होना चाहते हैं। –

+0

अच्छा दृष्टिकोण। मैं इस बात को रोक रहा था कि अब तक यह –

-1

मैं AuthorizeAttribute पर पढ़ने की सलाह (here देखें)। इसके अलावा, क्या आपने this पोस्ट देखा है? यह प्रमाणीकरण विशेषता innards को ओवरराइड करने और IPrincipal और IIDentity का उपयोग करने के तरीके पर कैसे चला जाता है।

1

मैं सुझाव दूंगा कि आप तर्क/नियंत्रक से तर्क खींचें और उस तर्क को संभालने के लिए एक डोमेन क्लास बनाएं।

क्रिया विधियों को वास्तव में केवल डेटा प्राप्त करने और डेटा को देखने के साथ ही सौदा करना चाहिए। आप अपनी आवश्यकताओं को संभालने के लिए पर्याप्त सामान्य बना सकते हैं लेकिन एक जिम्मेदारी प्रिंसिपल का भी पालन करेंगे।

public class AuthorizedToEdit 
{ 
    protected override bool AuthorizeCore(string user, int itemId) 
    { 
     var userName = httpContext.User.Identity.Name; 

     var authUsers = SubmissionRepository.GetAuthoriedUsers(itemId); 

     return authUsers.Contains(user); 
    } 
} 

यह भी आप