2011-03-29 7 views
11

मेरे पास वर्तमान में एक प्रोजेक्ट है जो मुझे भूमिकाओं के बारे में एक समस्या में भाग गया है और सोचा था कि मुझे समस्या को सर्वोत्तम तरीके से संभालने के तरीके पर कुछ राय मिलेंगी।एमवीसी में एकाधिक भूमिकाएं प्रबंधित करना - एक्शन-आधारित एक्सेसिबिलिटी

प्रणाली संपादन योग्य, लचीला भूमिकाओं है कि विशिष्ट क्षेत्रों में से न केवल का उपयोग, लेकिन यह भी प्रणाली कार्यों का उपयोग (जोड़ना, उपयोगकर्ता का संपादन उपयोगकर्ता, रिपोर्ट आदि देखने) पर नियंत्रण की आवश्यकता होगी

प्रणाली वर्तमान में उपयोगकर्ताओं की अनुमति देता है कई भूमिकाएं करने के लिए, तो उन भूमिकाओं में से प्रत्येक को स्पष्ट रूप से परिभाषित किया गया है पहुँच/कार्यों के क्षेत्रों, उदाहरण के लिए:

  • भूमिका एक क्षेत्रों 1,2,3 उपयोग कर सकते हैं और उपयोगकर्ताओं को जोड़ने कर सकते हैं।
  • भूमिका बी क्षेत्रों 1,5,7 तक पहुंच सकता है और उपयोगकर्ताओं को संशोधित कर सकता है।
  • भूमिका सी क्षेत्रों को 4,6 तक पहुंच सकता है और केवल उपयोगकर्ताओं को देख सकता है।

इसलिए उपयोगकर्ता भूमिका ए और सी में हो सकता है, और इस प्रकार पहुंच: 1,2,3,4 और 6, और उपयोगकर्ताओं को जोड़ और देख सकता है। जब यह instantiated है इसे से सभी गुणों की खींचती

Dictionary<string,bool> 

तो:

मेरी पहली समाधान एक शब्दकोश है कि इतनी तरह एक शब्दकोश में पहुँच/पहुंच विकल्प के संभावित क्षेत्रों के सभी स्टोर होगा बनाने के लिए था डेटाबेस और फिर यह निर्धारित करने के लिए भूमिका निभाता है कि वे सुलभ हैं या नहीं।

वर्तमान में यह सब ठीक काम करता है - हालांकि परियोजना काफी जावास्क्रिप्ट/jQuery गहन है इसलिए इनमें से कई विकल्पों को क्लाइंट-साइड फ़ंक्शंस द्वारा बुलाया जाता है। , मैं निम्नलिखित बातें के बारे में सोच रहा हूँ तो मूल रूप से

<%if(AccessDictionary[key]) 
    //Enable or Disable Action 
<%}%> 

:: मैं के साथ इन क्लाइंट पक्ष कार्यों के सभी रैप करने के लिए होने से बचने की कोशिश कर रहा हूँ

  1. में एक उपयोगकर्ता के लॉग के बाद, क्या इस शब्दकोश को स्टोर करने का सबसे अच्छा तरीका है? स्थिर? सत्र में?
  2. भंडारण का सबसे अच्छा तरीका क्या होगा कि शब्दकोश को आसानी से देखने में आसानी से पहुंचाया जा सके? (जैसा कि मैं वर्तमान में अपने क्लाइंट-साइड फ़ंक्शंस को लपेटने के लिए कोई रास्ता नहीं देखता)

कोई सलाह या विचारों की बहुत सराहना की जाएगी!

+0

क्या यह web.config में स्थान आधारित प्राधिकरण सुरक्षा सेटिंग द्वारा नियंत्रित नहीं किया जा सकता है? – Holystream

उत्तर

20

मैं इस जानकारी को प्रमाणीकरण कुकी के उपयोगकर्ता डेटा हिस्से में संग्रहीत करूंगा। तो जब में एक उपयोगकर्ता के लॉग:

public ActionResult Login(string username, string password) 
{ 
    // TODO: validate username/password couple and 
    // if they are valid get the roles for the user 

    var roles = "RoleA|RoleC"; 
    var ticket = new FormsAuthenticationTicket(
     1, 
     username, 
     DateTime.Now, 
     DateTime.Now.AddMilliseconds(FormsAuthentication.Timeout.TotalMilliseconds), 
     false, 
     roles 
    ); 
    var encryptedTicket = FormsAuthentication.Encrypt(ticket); 
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket) 
    { 
     // IIRC this property is only available in .NET 4.0, 
     // so you might need a constant here to match the domain property 
     // in the <forms> tag of the web.config 
     Domain = FormsAuthentication.CookieDomain, 
     HttpOnly = true, 
     Secure = FormsAuthentication.RequireSSL, 
    }; 
    Response.AppendCookie(authCookie); 
    return RedirectToAction("SomeSecureAction"); 
} 

तो मैं एक कस्टम authroize विशेषता है जो पढ़ने की देखभाल और प्रमाणीकरण टिकट पार्स करने और HttpContext में एक सामान्य उपयोगकर्ता स्टोर करेगा लिखेंगे।अपने इसी भूमिकाओं के साथ उपयोगकर्ता संपत्ति:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext.User.Identity.IsAuthenticated) 
     { 
      var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; 
      if (authCookie != null) 
      { 
       var ticket = FormsAuthentication.Decrypt(authCookie.Value); 
       var roles = ticket.UserData.Split('|'); 
       var identity = new GenericIdentity(ticket.Name); 
       httpContext.User = new GenericPrincipal(identity, roles); 
      } 
     } 
     return base.AuthorizeCore(httpContext); 
    } 
} 

इसके बाद आप अपने नियंत्रकों को सजाने सकता है/इस विशेषता के साथ क्रियाओं को संचालित करने के लिए प्राधिकरण:

// Only users that have RoleA or RoleB can access this action 
// Note that this works only with OR => that's how the base 
// authorize attribute is implemented. If you need to handle AND 
// you will need to completely short-circuit the base method call 
// in your custom authroize attribute and simply handle this 
// case manually 
[MyAuthorize(Roles = "RoleA,RoleB")] 
public ActionResult Foo() 
{ 
    ... 
} 

आदेश कोई उपयोगकर्ता किसी भूमिका बस में है कि क्या जांच करने के लिए में:

bool isInRole = User.IsInRole("RoleC"); 

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

अब यदि आपको प्रत्येक क्रिया में इस मानचित्रण की आवश्यकता है और विचारों को दोहराया जा सकता है और उबाऊ हो सकता है। यह वह जगह है जहां वैश्विक कस्टम एक्शन फ़िल्टर खेलते हैं (वे वास्तव में एएसपी.नेट एमवीसी 2 में मौजूद नहीं हैं, केवल एएसपी.नेट एमवीसी 3 में हैं, इसलिए आपको इस एक्शन फ़िल्टर से सजाए गए बेस कंट्रोलर की आवश्यकता हो सकती है जो समान या कम समान होती है कार्यक्षमता)। आप बस इस तरह के ग्लोबल एक्शन फ़िल्टर को परिभाषित करते हैं जो प्रत्येक क्रिया के बाद निष्पादित करता है और व्यूडेटा (पवित्र .... में कुछ आम दृश्य मॉडल इंजेक्ट करता है, विश्वास नहीं कर सकता कि मैं उन शब्दों का उच्चारण कर रहा हूं) और इस प्रकार इसे सभी विचारों के लिए एक ट्रान्सवर्स में उपलब्ध कराया गया है अन्य क्रियाओं के तरीके।

और अंत में आप साइट के विभिन्न क्षेत्रों को शामिल करने या नहीं करने के लिए उन बूलियन मान गुणों की जांच करेंगे। जहां तक ​​जावास्क्रिप्ट कोड का संबंध है, यदि यह साइट के अविश्वसनीय रूप से AJAXifying क्षेत्रों है तो यदि उन क्षेत्रों को डोम में मौजूद नहीं है तो यह कोड नहीं चलेगा। और यदि आपको अधिक बढ़िया दाग नियंत्रण की आवश्यकता है तो आप उपयोगकर्ता के प्राधिकरणों पर अपने बाहरी जावास्क्रिप्ट कार्यों को संकेत देने के लिए हमेशा अपने DOM तत्वों पर HTML5 data-* विशेषताओं का उपयोग कर सकते हैं।

+0

सामान्य डारिन के रूप में बहुत गहन उत्तर के लिए धन्यवाद। मैं इस तरह कुछ एकीकृत करने के लिए देखता हूँ! इसके अलावा - मैं आपको "पवित्र ...." व्यूडाटा का उल्लेख करने के लिए एक और +1 दूंगा। :) –

+0

यदि आप कुकीज में संवेदनशील जानकारी (जैसे उपयोगकर्ता भूमिकाएं) स्टोर करने जा रहे हैं, तो सुनिश्चित करें कि आपके पास नवीनतम नवीनतम .NET पैच हैं। फॉर्म्स प्रमाणीकरण में असुरक्षा होती थी। एंटीप्ट()। – Ryan

+0

इसके अलावा, मुझे वास्तव में डेटा- * विचार पसंद है। – Ryan

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