Django भूमिका आधारित विचारों?




architecture acl (8)

मैं इस पर कुछ इनपुट की तलाश कर रहा हूं कि यह कैसे अन्य आर्किटेक्ट करेगा। मैं कक्षा (डीजेंगो समूह) आधारित विचार प्रदान करने जा रहा हूं।

उदाहरण के लिए, उपयोगकर्ता के समूह निर्धारित करेंगे कि वह किस दृश्य / टेम्प्लेट को एक्सेस कर पाएंगे। मैं एक तालिका में फ़ंक्शंस को देखने के लिए पथ को संग्रहीत करने के बारे में सोच रहा हूं ताकि उपयोगकर्ता के लिंक बार में क्या होगा। ये टेम्प्लेट भरने वाली पंक्तियों को निर्धारित करने के लिए फ़िल्टर विनिर्देशों को भी संग्रहीत किया जा सकता है।

एक अच्छा उदाहरण एक अस्पताल नर्सिंग इकाइयां है। एक यूनिट पर नर्सों को पूरे अस्पताल के रोगियों को देखने की जरूरत नहीं है। उन्हें केवल अपने रोगियों को देखने की जरूरत है एक ही इकाई के डॉक्टरों को केवल उन मरीजों को देखने की जरूरत है, लेकिन उन्हें बहुत अधिक कार्यक्षमता तक पहुंच होनी चाहिए।

क्या यह कुछ तीसरे पक्ष के आवेदन के माध्यम से किया गया है? और आप इस समस्या का कैसे सामना करेंगे?

धन्यवाद, पीट


यदि आपको असली प्रति-वस्तु ACL की आवश्यकता नहीं है, तो आप केवल Django अनुमति प्रणाली का उपयोग कर सकते हैं सभी उपलब्ध अनुमतियों की सूची प्राप्त करने के लिए:

from django.contrib.auth.models import Permission
perms = Permission.objects.all()

अन्य प्रमाणीकरण और प्राधिकरण स्रोतों के लिए एक API है , इसलिए आपको इस अनुमति तालिका के साथ छड़ी करने की आवश्यकता नहीं है।

आप इस प्राधिकरण मॉडल (आरबीएसी) के संदर्भ में अपनी आवश्यकताओं को फिट करने के लिए यह डीजेंगो सिस्टम हैक कर सकते हैं या आप एसीएल जैसे समाधान के साथ आ सकते हैं।



हमें एक समान समस्या थी। Django के समूह वास्तव में इसके लिए अनुकूल नहीं हैं, लेकिन आप इन्हें शोर कर सकते हैं।

जिस प्रकार हमने किया, वह इस प्रकार था:

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

तब जब आप किसी उपयोगकर्ता को रिकॉर्ड की सूची प्रदर्शित करते हैं, तो आप दो समूहों के संयोजन के आधार पर फ़िल्टर करते हैं। किसी उपयोगकर्ता को दिए गए ऑब्जेक्ट को देखने के लिए सभी संबद्ध समूह अनुमतियां होनी चाहिए।

यदि आपके सिस्टम की आवश्यकता है, तो आप अलग-अलग कई नकारात्मक मानकों की अनुमति रख सकते हैं, या अलग-अलग पढ़ने / लिखने की अनुमतियाँ रख सकते हैं। आप मेटा-समूह (डॉक्टर, नर्स) का एक सेट भी परिभाषित कर सकते हैं, जो परिणामस्वरूप आपके वास्तविक दृश्य को पुनः प्राप्त करने के लिए आपके लुकअप फ़िल्टर का परिणाम है।

जहां तक ​​आपकी लिंक-बार समस्या होती है, आप उस प्रोग्राम को उन प्रोग्रामों से उत्पन्न कर सकते हैं जो उपयोगकर्ता को देख या संपादित कर सकते हैं, और फिर get_absolute_url() प्रकार फ़ंक्शन (शायद इसे get_index_url() ) वस्तु के प्रत्येक वर्ग के सूचकांक के लिए लिंक वापस करने के लिए

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


मेरे पास ऐसी ही समस्या थी, जो बहुत पहले नहीं थी हमारे समाधान ने चाल किया, हालांकि यह आपकी स्थिति के लिए बहुत आसान हो सकता है। जैसे हर कोई सुझाव दे रहा है, हमने मॉडल के साथ उपयोगकर्ता इंटरैक्शन को नियंत्रित करने के लिए डीजेंगो अनुमति प्रणाली का उपयोग किया था। हालांकि, हम सिर्फ उपयोगकर्ताओं के समूह की कोशिश नहीं कर रहे थे, हमने जेनेरिक फ़ोरिसन के माध्यम से ऑब्जेक्ट भी समूहबद्ध किए हैं।

हमने एक ऐसा मॉडल बनाया है जो पदानुक्रमों को विकसित करने की अनुमति देने के लिए स्वयं से जुड़ा हुआ है।

class Group( models.Model ):
    name = models.CharField( ... )
    parent = models.ForeignKey( 'self', blank=True, null=True)
    content_type = models.ForeignKey( ContentType )
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey( 'content_type', 'object_id' )
    ...

इसे काम करने के लिए, हमने डीजेंगो उपयोगकर्ता मॉडल के उपयोगकर्ता प्रोफ़ाइल के रूप में सेवा करने के लिए एक मॉडल भी बनाया है। यह सब कुछ ऊपर समूह मॉडल से जुड़ा एक ManyToManyField था। इससे हमें उपयोगकर्ताओं को शून्य या अधिक समूहों तक पहुंचने की अनुमति मिल गई है। ( प्रलेखन )

class UserProfile( models.Model ):
    user = models.ForeignKey( User, unique=True )
    groups = models.ManyToManyField( Group )
    ...

यह हमें दोनों दुनिया का सबसे अच्छा दिया और हमें डीजेंगो की अनुमति प्रणाली में सबकुछ करने की कोशिश करने से रोक दिया। मैं इस मूलभूत सेटअप का उपयोग कर खेल की सामग्री पर उपयोगकर्ता की पहुंच को नियंत्रित करने के लिए उपयोग कर रहा हूं (कुछ उपयोगकर्ता संपूर्ण लीग का उपयोग कर सकते हैं, कुछ केवल एक या दो सम्मेलन, कुछ केवल व्यक्तिगत टीमों तक पहुँच सकते हैं), और यह उस स्थिति में अच्छी तरह से काम करता है। यह आपकी आवश्यकताओं के अनुरूप पर्याप्त रूप से सामान्यीकृत हो सकता है


Pinot Noir शराब पर एक विशेषज्ञ के लिए एक साइट पर हमने विभिन्न मानदंडों के आधार पर प्रति-ऑब्जेक्ट एक्सेस बनाया है। अगर इनबाउंड लिंक में एक रेफेरर फ़ील्ड होता है जो वैनिएयर के वैनिएयर के डोमेन नाम से मेल खाता होता है, तो उपयोगकर्ता को 'वाइनरी टोकन' मिला, जो सभी वाइनरीज़ से संबंधित सभी लेखों, चखने वाले नोट्स आदि में विस्तारित हो गया। चखने की घटनाओं पर हम लोगों के लिए 'नामांकित टोकन' का इस्तेमाल करते हैं और उन्होंने साइट के विशिष्ट भागों तक पहुंच प्रदान की है। हम इसका उपयोग इंजन मकड़ियों को खोजने के लिए कुछ प्रकार की अनुमतियों को देने के लिए करते हैं और फिर यह सुनिश्चित कर लें कि उन खोज इंजनों से आने वाले लिंक की अनुमति समान है क्योंकि स्पाइडर ने (यानी कोई क्लोकिंग गेम) नहीं किया था।

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

असल में यह एक अजीब तरह का एसीएल सिस्टम है यह यांत्रिकी बनाने के लिए मुश्किल नहीं था सभी परिस्थितियों में यह निर्धारित करने में है कि किस परिस्थितियों में टोकन बाल्टी में जाते हैं।


Django पहले से ही एक समूह और अनुमति प्रणाली है, जो आपके उद्देश्य के लिए पर्याप्त हो सकता है

http://docs.djangoproject.com/en/dev/topics/auth/

आम तौर पर आपके कोड में आप जांचते हैं कि उपयोगकर्ता की अनुमति है या नहीं। एक प्रयोक्ता के पास अपनी अनुमतियां हैं और वह उन समूहों की है जो वह संबंधित हैं। आप इसे व्यवस्थापक कंसोल से बहुत आसानी से संचालित कर सकते हैं।

आपको देखने के लिए दो भागों हैं।

  1. जांच लें कि किसी पृष्ठ का अनुरोध करने वाला उपयोगकर्ता ऐसा करने की अनुमति देता है।
  2. अगर उपयोगकर्ता को उसकी अनुमति है तो उसे केवल लिंक दिखाएं

1. आप डेकोरेटर में अनुमतियों की जांच कर सकते हैं जैसे:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def some_view(request):

2. वर्तमान में लॉग-इन उपयोगकर्ता की अनुमतियाँ टेम्पलेट चर {{perms}} में संग्रहीत हैं। यह कोड उपरोक्त के समान अनुमति की जांच करता है

{% if perms.polls.can_vote %}
    <a href="/vote">vote</a>
{% endif %}

लिंक की एक सूची जेनरेट करने के लिए आप उपयोगकर्ता के बारे में दोबारा बना सकते हैं। Get_all_permissions () और एक शब्दकोश से लिंक (या फ़ंक्शन जो लिंक उत्पन्न करता है) प्राप्त करें:

def more_elaborate_list_of_links_for_a_perm(user):
    return ["/link1", ...]

_LINKS = {
    'polls.can_vote' : lambda u: ["/user/specific/link/" + u.id],
    'polls.can_close': lambda u: ['/static/link/1', 'static/link/2'],
    'polls.can_open' : more_elaborate_list_of_links_for_a_perm
}

def gen_links(user):
    # get_all_permissions also gets permissions for users groups
    perms = user.get_all_permissions()
    return sum((_LINKS[p](user) for p in perms if p in _LINKS), [])

शायद कई अन्य दृष्टिकोण हैं


यह सवाल अक्टूबर 2009 में पूछा गया है और समस्या अभी भी जुलाई 2012 में मौजूद है।

मैंने एक अच्छी भूमिका-आधारित ऐप खोजी है, और django-permission को सबसे अच्छा परिणाम के रूप में पाया।

तीन महत्वपूर्ण विशेषताएं जिनकी मुझे जरूरत थी भूमिकाएं थी , सज्जाकार और टेम्पलटाटग देखें; जाहिरा तौर पर django-permissions में वे सभी हैं इसके उपयोग के लिए इसका दस्तावेज पढ़ें

केवल दोष यह है कि यह विकास के अधीन है।


Django में भूमिका आधारित अनुमतियों के बारे में एक नया रोचक प्रोजेक्ट है: http://bitbucket.org/nabucosound/django-rbac





acl