DDD CQRS - प्रति-क्वेरी और प्रति-कमांड प्राधिकरण


15

सारांश

CQRS / DDD में प्राधिकरण को प्रति-कमांड / क्वेरी लागू किया जाना चाहिए या नहीं?

मैं पहली बार डीडीडी CQRS पैटर्न का अधिक या कम सख्ती से उपयोग करके एक ऑनलाइन एप्लिकेशन विकसित कर रहा हूं। मैं कुछ समस्या से टकराया, जो मुझे वास्तव में अपना सिर नहीं मिला।

मैं जिस एप्लिकेशन का निर्माण कर रहा हूं, वह एक अंडरगारमेंट एप्लिकेशन है जिससे लोग लीडर बना सकते हैं, साथ ही अन्य लोगों को उन्हें देखने / संपादित करने / हटाने की अनुमति दे सकते हैं, जैसे कि कर्मचारी। एक बही के निर्माता को उस बही के उपयोग के अधिकारों को संपादित करने में सक्षम होना चाहिए जो उसने बनाया था। यहां तक ​​कि स्वामित्व बदल सकता है। डोमेन में दो समुच्चय हैं TLedger और TUser

मैंने सुरक्षा, प्राधिकरण आदि से संबंधित DDD / CQRS कीवर्ड के साथ बहुत सी पोस्ट पढ़ीं, उनमें से अधिकांश ने कहा कि प्राधिकरण एक सामान्य सबडोमेन था , जब तक कि कोई एक सुरक्षा एप्लिकेशन का निर्माण नहीं कर रहा था।

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

यह डीडीडी ट्यूटोरियल में उस जगह के चारों ओर बताया गया है जहां कमांड सर्वव्यापी भाषा का हिस्सा हैं। वे सार्थक हैं। वे ठोस कार्य हैं जो "वास्तविक चीज़" का प्रतिनिधित्व करते हैं।

क्योंकि उन सभी कमांड और क्वेरी वास्तविक क्रिया हैं जो उपयोगकर्ता "वास्तविक जीवन" में निष्पादित करेंगे, क्या प्राधिकरण के कार्यान्वयन को इन सभी "कमांड" और "प्रश्नों" के साथ जोड़ा जाना चाहिए? एक उपयोगकर्ता के पास उदाहरण के लिए TLedger.addTransaction () लेकिन नहीं TLedger.removeTransaction () निष्पादित करने के लिए प्राधिकरण होगा। या, किसी उपयोगकर्ता को "getSummaries ()" क्वेरी निष्पादित करने की अनुमति होगी, लेकिन "getTransactions ()" नहीं।

एक त्रि-आयामी मानचित्रण, उपयोगकर्ता-बही-आदेश या उपयोगकर्ता-बही-खाता के रूप में मौजूद होगा जिससे अभिगम अधिकार निर्धारित किया जा सके।

या, डिकोड किए गए तरीके से, "अनुमतियाँ" नाम एक उपयोगकर्ता के लिए पंजीकृत किया जाएगा। अनुमतियाँ जो तब विशिष्ट आदेशों के लिए मैप की जाएंगी। उदाहरण के लिए, "ManageTransactions" की अनुमति उपयोगकर्ता को "AddTransaction ()", "RemoveTransaction ()", आदि निष्पादित करने की अनुमति देगा।

  1. अनुमतियाँ मैपिंग उपयोगकर्ता -> खाता बही -> आदेश / क्वेरी

  2. अनुमतियाँ मैपिंग उपयोगकर्ता -> खाता बही -> अनुमति -> आदेश / क्वेरी

यह सवाल का पहला हिस्सा है। या संक्षेप में, CQRS / DDD में प्राधिकरण को प्रति-आदेश या प्रति-क्वेरी को लागू किया जाना चाहिए? या, क्या प्राधिकरण को आदेशों से अलग कर दिया जाना चाहिए?

दूसरे, अनुमति के आधार पर प्राधिकरण के विषय में। एक उपयोगकर्ता को अपने लेजर पर अनुमतियों का प्रबंधन करने में सक्षम होना चाहिए या लेजर पर उसे प्रबंधित करने की अनुमति दी जानी चाहिए।

  1. प्राधिकरण प्रबंधन आदेश लेजर में होता है

मैंने लेज़र एग्रीगेट में ईवेंट्स / कमांड्स / हैंडलर को जोड़ने का विचार किया , जैसे कि अनुदानप्राप्ति (), रिवोकपर्मिशन (), आदि। इस मामले में, उन नियमों को लागू करना कमांड हैंडलर में होगा। लेकिन इसके लिए सभी कमांड्स को उस कमांड को जारी करने वाले यूजर की आईडी को शामिल करना होगा। तब मैं TLedger में जांच करूँगा कि क्या उस उपयोगकर्ता के लिए उस आदेश को निष्पादित करने के लिए अनुमति मौजूद है।

उदाहरण के लिए :

class TLedger{ 
    function addTransactionCmdHandler(cmd){
        if (!this.permissions.exist(user, 'addTransaction')
            throw new Error('Not Authorized');
    }
}
  1. प्राधिकरण प्रबंधन उपयोगकर्ता में आदेश देता है

अन्य तरीकों से TUser में अनुमतियों को शामिल किया जाएगा। TUser के पास अनुमतियों का एक सेट होगा। तब, TLedger कमांड संचालकों में, मैं उपयोगकर्ता को पुनः प्राप्त करूंगा और जांच करूंगा कि उसके पास कमांड निष्पादित करने की अनुमति है या नहीं। लेकिन इसके लिए मुझे हर TLedger कमांड के लिए TUser एग्रीगेट लाना होगा।

class TAddTransactionCmdHandler(cmd) {
    this.userRepository.find(cmd.userId)
    .then(function(user){
        if (!user.can(cmd)){
            throw new Error('Not authorized');
        }
        return this.ledgerRepository.find(cmd.ledgerId);
    })
    .then(function(ledger){
        ledger.addTransaction(cmd);
    })

}
  1. सेवा के साथ एक और डोमेन

एक और संभावना एक और प्राधिकरण डोमेन को पूरी तरह से मॉडल करने की होगी। यह डोमेन एक्सेस राइट्स, ऑथराइजेशन आदि में रुचि रखता है। अकाउंटिंग सबडोमेन तब इस ऑथराइजेशन डोमेन को एक्सेस करने के लिए किसी सर्विस का इस्तेमाल करेगा AuthorizationService.isAuthorized(user, command)

class TAddTransactionCmdHandler(cmd) {
    authService.isAuthorized(cmd)
    .then(function(authorized){
        if (!authorized) throw new Error('Not authorized');
        return this.ledgerRepository.find(cmd.ledgerId)
    })
    .then(function(){
        ledger.addTransaction(cmd);
    })

}

किस निर्णय से सबसे अधिक "DDD / CQRS" होगा?


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

प्रत्येक लेनदेन में निष्पादन नीति हो सकती है। प्रत्येक उपयोगकर्ता को एक अयस्क से अधिक समूहों से संबंधित होना चाहिए, प्रत्येक समूह के पास एक पहुंच प्रोफ़ाइल होगी जिसमें निर्दिष्ट किया जाएगा कि कौन से लेनदेन की अनुमति है। रन-टाइम पर, लेन-देन निष्पादित करने से पहले, नीति निष्पादित उपयोगकर्ता के लिए एकत्रित प्रोफाइल के खिलाफ जाँच की जाती है। बेशक, यह कहा से आसान है।
NoChance

जवाबों:


5

पहले प्रश्न के लिए मैं कुछ इसी तरह से संघर्ष कर रहा था। अधिक से अधिक मैं एक तीन चरणीय प्राधिकरण योजना की ओर झुक रहा हूं:

1) कमांड / क्वेरी स्तर पर प्राधिकरण "क्या इस उपयोगकर्ता को कभी भी इस कमांड को निष्पादित करने की अनुमति है?" MVC ऐप में इसे संभवतः नियंत्रक स्तर पर नियंत्रित किया जा सकता है, लेकिन मैं एक सामान्य प्री-हैंडलर का विकल्प चुन रहा हूं जो वर्तमान उपयोगकर्ता और निष्पादन कमांड के आधार पर अनुमतियों की दुकान को क्वेरी करेगा।

2) "क्या यह उपयोगकर्ता" कभी भी इस संस्था को एक्सेस करने की अनुमति देता है? "के अनुप्रयोग सेवा के अंदर प्राधिकरण को अनुमति है?" मेरे मामले में यह संभवतः रिपॉजिटरी पर फिल्टर के माध्यम से एक अंतर्निहित जांच होगी - मेरे डोमेन में यह है मूल रूप से एक TenantId के साथ संगठन की थोड़ी अधिक ग्रैन्युलैरिटी।

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

मुझे इस विचार पर दूसरों की प्रतिक्रियाएँ सुनना अच्छा लगेगा - यदि आप चाहें तो इसे फाड़ दें (यदि आप कुछ विकल्प प्रदान करें तो :) करें)


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

0

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

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