जावा में गतिशील कोड मूल्यांकन - चतुर या मैला?


30

मैं अपने आवेदन के लिए जावा में एक लचीली एसीएल रूपरेखा बनाने की कोशिश कर रहा हूं।

कई एसीएल ढांचे नियमों के एक श्वेतसूची पर बनाए गए हैं, जहां एक नियम मालिक के रूप में है : कार्रवाई: संसाधन । उदाहरण के लिए,

  • "जॉन संसाधन FOOBAR-1 देख सकते हैं"
  • "MARY संसाधन FOOBAR-1 देख सकते हैं"
  • "MARY संसाधन FOOBAR-1 को संपादित कर सकते हैं"

यह आकर्षक है क्योंकि नियमों को आसानी से क्रमबद्ध किया जा सकता है / एक डेटाबेस के लिए जारी रखा जा सकता है। लेकिन मेरे आवेदन में जटिल व्यावसायिक तर्क है। उदाहरण के लिए,

  • "वरिष्ठता के 5 वर्षों में विभाग 1 के सभी उपयोगकर्ता संसाधन FOOBAR-1 देख सकते हैं, अधिकृत नहीं"
  • "विभाग 2 में सभी उपयोगकर्ता, यदि दिनांक 03/15/2016 के बाद है, तो संसाधन FOOBAR-2 देख सकते हैं, अन्यथा अधिकृत हैं"

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

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

  • return user.getDept() == 1 && user.seniority > 5;

ऐसा करने में, विधेय आसानी से डेटाबेस में बनाए रखा जा सकता है।

क्या यह चतुर है ? क्या यह मैला है ? क्या यह नौटंकी है ? क्या यह ओवर-इंजीनियर है ? क्या यह सुरक्षित है (जाहिर है, जावा राइनो इंजन को सैंडबॉक्स कर सकता है)।


8
संकलित आवेदन में तर्क रखने पर इन व्यावसायिक नियमों को डेटाबेस में धकेलने की कोशिश करने से क्या लाभ है?
विंस्टन इवर्ट

6
@InstonEWert नियमों को बाहरी बनाने से आवेदन को फिर से जोड़ने और पुनर्वितरित करने की आवश्यकता समाप्त हो जाती है, एक नियम को बदला, जोड़ा या हटाया जाना चाहिए।
ट्विटोफर


2
दिलचस्प सवाल! मैं एक जवाब देखना चाहता हूं जो सुरक्षा पर ध्यान केंद्रित नहीं करता है, बल्कि ऐसे समाधान के रखरखाव, विश्वसनीयता और उपयोग में आसान पहलुओं पर ध्यान केंद्रित करता है।
जैतून

6
यह आउटलुक ईमेल नियमों के समान लगता है जो अनिवार्य रूप से एक नियम इंजन है जो उपयोगकर्ता द्वारा कॉन्फ़िगर करने योग्य है।

जवाबों:


37

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

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


16
लेकिन क्या जावास्क्रिप्ट का उपयोग यहां डीएसएल जैसी विभाजनकारी भाषा के रूप में नहीं किया जाएगा? हम आवश्यक डेटा (केवल पढ़ने के लिए) सेट करते हैं, एक फ़ंक्शन में स्निपेट लपेटते हैं, और सुरक्षित रूप से इसका मूल्यांकन करते हैं। चूंकि कोड एक बूलियन को छोड़कर कुछ नहीं कर सकता है, इसलिए यहां कोई दुर्भावनापूर्ण अवसर नहीं होगा।
अमोन

6
@Twittopher कुछ predicates का मूल्यांकन करने के लिए पूरे जावास्क्रिप्ट इंजन को खींच रहा है, अभी भी 1) पूर्ण ओवरकिल, 2) जोखिम भरा और 3) मेरे लिए त्रुटि-प्रवण लगता है। बिंदु में मामला, आपने अपने उदाहरण के ==बजाय उपयोग किया ===। क्या आप वास्तव में ट्यूरिंग पूर्णता प्रदान करना चाहते हैं जब सभी नियम यकीनन समाप्त होने चाहिए? जावा और जावास्क्रिप्ट के बीच सभी इंटरैक्शन सुनिश्चित करने के लिए हुप्स के माध्यम से कूदने के बजाय कोषेर हैं, तो आप सिर्फ एक साधारण पार्सर और इंटरप्रिटर की तरह क्यों नहीं लिखते हैं जैसा कि किलियन ने सुझाया था? यह अपनी आवश्यकताओं और सुरक्षित करने के लिए दर्जी के लिए बहुत आसान हो जाएगा। ANTLR या कुछ और का उपयोग करें।
डोवल

6
@Doval लेखन एक छोटे से DSL बिल्कुल रॉकेट विज्ञान नहीं है, और मैं 3hrs में 5 दिनों के लिए एक सरल भाषा कोड़ा मार सकता है। लेकिन ऐसा लगता है कि 1) पूर्ण ओवरकिल, 2) जोखिम भरा है, और 3) मुझसे त्रुटि-प्रवण है। क्या आप वास्तव में एक पूरी मिनी-भाषा लिखना चाहते हैं? क्या होगा अगर कुछ व्यावसायिक नियम अपेक्षा से अधिक जटिल हैं और पूरी तरह से चित्रित भाषा की आवश्यकता है? क्या आप नॉट इनवर्टेड हियर-सिंड्रोम से पीड़ित हैं? पहिए पर लगाम लगाने के बजाय, आप मौजूदा भाषा का उपयोग क्यों नहीं करते? पहले से ही युद्ध-परीक्षण वाली भाषा का उपयोग करना बहुत आसान है।
अमोन

14
@amon जब ऐसा होता है, तो आपको एक वास्तविक नियम इंजन मिल जाता है (जो जावास्क्रिप्ट नहीं है) जैसे कि किलियन ने कहा। दोनों दृष्टिकोणों के जोखिम को समान करने के लिए भ्रामक है। ट्यूरिंग-पूर्ण भाषा के लिए दुभाषिया को सुरक्षित करने के आपके सभी प्रयासों को नष्ट करने के लिए केवल एक चूक होती है; यह एक घटिया प्रक्रिया है। गलती से एक छोटे से डीएसएल को खतरनाक बनाना बहुत कठिन है; यह एक additive प्रक्रिया है। आप जिस तरह की गलती कर रहे हैं, वह वाक्यविन्यास के पेड़ को गलत तरीके से व्याख्या कर रहा है, और वह इकाई परीक्षण किया जा सकता है। आप संभवतः दुभाषिया को क्षमता प्रारूप को हार्ड ड्राइव देने के लिए नहीं जा रहे हैं।
डोभाल

4
@amon: भले ही js स्निपेट के साइड इफेक्ट्स न हों, लेकिन यह बूलियन वैल्यू वापस नहीं करने का विकल्प चुन सकता है :while (true) ;
Bergi

44

मैंने ऐसा किया है, और मैं सलाह देता हूं कि आप ऐसा न करें।

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

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

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


3

मेरे पास डेटाबेस में कोड नहीं होगा। लेकिन आप डेटाबेस को फ़ंक्शन नाम और फिर उन्हें कॉल करने के लिए प्रतिबिंब का उपयोग करके कुछ समान कर सकते हैं। जब आप एक नई शर्त जोड़ते हैं, तो आपको इसे अपने कोड और अपने डेटाबेस में जोड़ना होता है, लेकिन आप उन परिस्थितियों और मापदंडों को जोड़ सकते हैं जो उन्हें काफी जटिल मूल्यांकन बनाने के लिए पास हो जाते हैं।

दूसरे शब्दों में, यदि आपके पास विभागों की संख्या है, तो UserDepboxIs की जाँच और आज के बाद की जाँच करना आसान होगा और फिर उन्हें जोड़कर एक विभाग = 2 और आज> 03/15/2016 पर भेज दें। यदि आप एक TodayIsBefore की जाँच करना चाहते हैं ताकि आप अनुमति को समाप्त कर सकें, तो आपको TodayIsBefore फ़ंक्शन लिखना होगा।

मैंने इसे उपयोगकर्ता की अनुमति के लिए नहीं किया है, लेकिन डेटा सत्यापन के लिए किया है, लेकिन यह काम करना चाहिए।


2

XACML वह समाधान है जिसकी आप वास्तव में तलाश कर रहे हैं। यह एक प्रकार का नियम इंजन है जो केवल एक्सेस कंट्रोल पर केंद्रित है। XACML, OASIS द्वारा परिभाषित एक मानक, तीन भागों को परिभाषित करता है:

  • एक वास्तुकला
  • एक नीति भाषा (जो वास्तव में आप चाहते हैं)
  • एक अनुरोध / प्रतिक्रिया योजना (आप प्राधिकरण के निर्णय के लिए कैसे पूछते हैं)।

वास्तुकला इस प्रकार है:

  • नीति निर्णय बिंदु (पीडीपी) वास्तुकला का मुख्य हिस्सा है। यह घटक है जो नीतियों के ज्ञात सेट के खिलाफ आने वाले प्राधिकरण अनुरोधों का मूल्यांकन करता है
  • पॉलिसी प्रवर्तन बिंदु (PEP) कोड का एक टुकड़ा है जो आपके एप्लिकेशन / API / सेवा की सुरक्षा करता है। पीईपी व्यावसायिक अनुरोध को स्वीकार करता है, एक एक्सएसीएमएल प्राधिकरण अनुरोध बनाता है, इसे पीडीपी को भेजता है, एक प्रतिक्रिया वापस प्राप्त करता है, और प्रतिक्रिया के अंदर निर्णय लागू करता है।
  • नीति सूचना बिंदु (पीआईपी) एक घटक है जो पीडीपी को डेटा के बाहरी स्रोतों से जोड़ सकता है जैसे एक एलडीएपी, एक डेटाबेस या एक वेब सेवा। जब पीईपी एक अनुरोध भेजता है तो पीआईपी काम में आता है जैसे "क्या ऐलिस डॉक्स # 12 देख सकता है?" और पीडीपी की एक नीति है जिसमें उपयोगकर्ता की आयु की आवश्यकता होती है। पीडीपी पीआईपी से पूछेगा "मुझे ऐलिस की उम्र दें" और फिर नीतियों को संसाधित करने में सक्षम होगा।
  • नीति प्रशासन बिंदु (PAP) वह स्थान है जहाँ आप संपूर्ण XACML समाधान (विशेषताओं को परिभाषित करना, नीतियाँ लिखना और PDP को कॉन्फ़िगर करना) का प्रबंधन करते हैं।

एक्सटेन्सिबल एक्सेस कंट्रोल मार्कअप लैंग्वेज - एक्सएसीएमएल आर्किटेक्चर

यहाँ आपका पहला उपयोग मामला कैसा दिखता है:

/*
 * All users in department 1 with over 5 years of seniority can VIEW resource FOOBAR-1, else not authorized
 * 
 */
 policy departmentOne{
    target clause department == 1
    apply firstApplicable
    /**
     * All users in department 1 with over 5 years of seniority can VIEW resource FOOBAR-1, else not authorized
     */
    rule allowFooBar1{
        target clause resourceId=="FOOBAR-1" and seniority>=5 and actionId=="VIEW"
        permit
    }
    rule denyOtherAccess{
        deny
    }

 }

आपका दूसरा उपयोग मामला होगा:

 /*
  * "All users in department 2, if the date is after 03/15/2016, can VIEW resource FOOBAR-2, else not authorized"
  *  
  */
  policy departmentTwo{
    target clause department == 1
    apply firstApplicable
    rule allowFooBar2{
        target clause resourceId=="FOOBAR-1" and seniority>=5 and currentDate>"2016/03/15":date and actionId=="VIEW"
        permit
    }
    rule denyOtherAccess{
        deny
    }
  }

आप संदर्भ का उपयोग करके दोनों मामलों को एक ही नीति में जोड़ सकते हैं:

  policyset global{
    apply firstApplicable
    departmentOne
    departmentTwo
  }

और आपने कल लिया!

आप XACML और ALFA पर और अधिक पढ़ सकते हैं:


0

आप वास्तव में यहाँ क्या चाहते हैं XACML । यह बहुत ज्यादा आपको वही देता है जो आप चाहते हैं। आपको जरूरी नहीं कि सभी भूमिकाओं को पूरी तरह से अलग करने के साथ पूर्ण वास्तुकला को लागू करना है ... यदि आपके पास केवल एक ही आवेदन है, तो आप संभवतः पीडीपी और पीईपी को अपने ऐप में बलाना और पीआईपी के साथ एकीकृत कर सकते हैं। आपका मौजूदा उपयोगकर्ता डेटाबेस है

अब, आपके एप्लिकेशन में कहीं भी आपको कुछ अधिकृत करने की आवश्यकता है, आप एक XACML अनुरोध बनाते हैं जिसमें उपयोगकर्ता, क्रिया और संदर्भ हैं, और XACML इंजन आपके द्वारा लिखे गए XACML नीति फ़ाइलों के आधार पर निर्णय करेगा। इन नीति फ़ाइलों को डेटाबेस में या फाइल सिस्टम पर, या जहाँ भी आप विन्यास रखना चाहते हैं, रख सकते हैं। Axiomatics का XACML XML प्रतिनिधित्व के लिए एक अच्छा विकल्प है जिसे ALFA कहा जाता है जो कच्चे XML की तुलना में पढ़ना थोड़ा आसान है, और ALFA नीतियों से XACML XML उत्पन्न करने के लिए एक ग्रहण प्लगइन है।


1
यह पूछे गए प्रश्न का उत्तर कैसे देता है?
gnat

वह विशेष रूप से एक बाहरी रूप से कॉन्फ़िगर प्राधिकरण प्रणाली को लागू करने की कोशिश कर रहा है। XACML बाहरी रूप से कॉन्फ़िगर किए गए प्राधिकरण सिस्टम पर जाने के लिए तैयार है जो अपने विशिष्ट उपयोग के मामले को बहुत अच्छी तरह से कवर करता है। मैं मानता हूँ कि यह डायनामिक कोड निष्पादन के अधिक सामान्य प्रश्न का एक बढ़िया उत्तर नहीं हो सकता है, लेकिन यह उनके विशिष्ट प्रश्न का एक अच्छा समाधान है।
Gregsymons

0

हमने अपनी वर्तमान कंपनी में ऐसा किया, और हम परिणामों से बहुत खुश हैं।

हमारे एक्सप्रेशन js में लिखे गए हैं, और हम उन्हें उन परिणामों को प्रतिबंधित करने के लिए भी उपयोग करते हैं जो उपयोगकर्ता ElasticSearch को क्वेरी करने से प्राप्त कर सकते हैं।

चाल यह सुनिश्चित कर रही है कि निर्णय लेने के लिए पर्याप्त जानकारी उपलब्ध है, ताकि आप कोड परिवर्तन के बिना जो भी अनुमति चाहते हैं, वास्तव में लिख सकें, लेकिन एक ही समय में इसे तेजी से रखते हुए।

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

अद्यतन करें:

XACML जैसा कुछ होना एक संगठन के लिए केंद्रीय वस्तु प्रबंधन बिंदु के रूप में बेहतर लगता है। हमारे उपयोग का मामला थोड़ा अलग है कि हमारे ग्राहकों ने यह सब चलाने के लिए आईटी विभाग नहीं किया है। हमें कुछ आत्म-निहित की आवश्यकता थी लेकिन जितना संभव हो उतना लचीलापन बनाए रखने की कोशिश की।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.