2013-06-18 10 views
11

प्रश्न का शीर्षक बहुत अधिक शुरू होता है: मैं कमांड के लिए प्राधिकरण कहां सत्यापित करूं?कमांड के लिए प्राधिकरण को सत्यापित करने के लिए कहां?

उदाहरण के लिए, जो कि अनुशंसित एक ग्राहक की स्थापना शामिल है:

  • MarkAsPreferred नियंत्रक कार्रवाई (Winforms या जो कुछ भी हो सकता है);
  • SetCustomerAsPreferredCommand;
  • SetCustomerAsPreferredCommandHandler;
  • Customer.MarkAsPreferred() (डोमेन);

मैं प्राधिकरण के लिए जाँच करने के लिए 3 स्थानों की पहचान की: (उपयोगकर्ता एक लिंक बटन नहीं देखना चाहिए/अगर वह/वह इसे करने के लिए पहुँच नहीं है) के प्रयोजनों के प्रदर्शित करने के लिए

  • यूआई;
  • नियंत्रक कार्रवाई उपयोगकर्ता को यह आदेश देने के लिए अधिकृत है कि यह आदेश कॉल करने के लिए अधिकृत है; आदेश हमेशा सफल होते हैं (सत्यापन के संबंध में, लेकिन मैं भी प्राधिकरण मान रहा हूं) और हमारे पास उपयोगकर्ता की पहुंच की कमी के बारे में सूचित करने का मौका है;
  • डोमेन तर्क को कॉल करने से पहले कमांड के अंदर;

SomeView.cshtml

if (authorizationService.Authorize("MarkCustomerAsPreferred)) 
{ 
    // show link 
} 

CustomerController

[HttpPost] 
public ActionResult MarkAsPreferred(Guid id) 
{ 
    if (!authorizationService.Authorize("MarkCustomerAsPreferred)) 
    { 
     return RedirectToAction("Unauthorized"); 
    } 

    var MarkCustomerAsPreferredCommand { Id = id }; 
    ... 
} 

MarkCustomerAsPreferredCommandHandler

public void Handle(MarkCustomerAsPreferredCommand command) 
{ 
    if (!authorizationService.Authorize("MarkCustomerAsPreferred")) 
    { 
     throw new Exception("..."); 
    } 

    customer.MarkAsPreferred(); 
} 

मेरा प्रश्न है: क्या मैं को 3 स्थानों में प्राधिकरण सत्यापित करने के लिए की आवश्यकता है या मैं केवल अति उत्साही हूं?

मैंने पूरे इंटरनेट पर खोज की लेकिन इसके बारे में कोई उदाहरण या संदर्भ नहीं मिला।

संपादित

के बाद और अधिक शोध और कुछ परीक्षण मैं डेनिस ताओब के रूप में व्यवहार (प्राधिकरण, सत्यापन, प्रवेश) जोड़ने के लिए आदेशों लपेटकर लगता सुझाव आसान है और लागू करने के लिए क्लीनर है।

मुझे this blog post मिला जो वास्तव में इस अवधारणा को समझाता है।

एक कमांड के लिए एकाधिक हैंडलर रखने के बारे में, मुझे प्रत्येक मूल कमांड के लिए प्रत्येक व्यवहार के लिए एक कमांड हैंडलर को लागू करने की आवश्यकता नहीं है, एक रैपिंग कमांड सभी हैंडलर को लपेट सकता है।

उत्तर

5

मैं अंतिम प्राधिकरण आदेश से निपटने के हिस्से के रूप आवेदन सेवा स्तर पर किया जाना चाहिए, जैसे लगता है। उदाहरण के लिए आप कमांड हैंडलर को प्राधिकरण हैंडलर से लपेट सकते हैं।

class AuthorizationHandler : IHandle<SetCustomerAsPreferred> { 

    IHandle<SetCustomerAsPreferred> innerHandler; 

    public AuthorizationHandler(IHandle<SetCustomerAsPreferred> handler) 
    { 
     innerHandler = handler; 
    } 

    public void Handle(SetCustomerAsPreferred command) 
    { 
     if (/* not authorized */) 
      throw ... 
     innerHandler.Handle(command); 
    } 

} 

class SetCustomerAsPreferredCommandHandler : IHandle<SetCustomerAsPreferred> { 

    public void Handle(SetCustomerAsPreferred command) 
    { 
     // do the work 
    } 

} 
+0

आदेश रैपिंग कार्यक्षमता जोड़ने के लिए एक अच्छा तरीका है, लेकिन यह कुछ सवाल उठता है: 1) यह संभावनाओं का एक बहुत खुल जाता है, उदाहरण के प्रवेश और सत्यापन के लिए; इसलिए प्रत्येक कमांड के लिए मैं एन कमांड हैंडलर (वास्तविक हैंडलर, लॉगिंग, सत्यापन, प्रमाणीकरण इत्यादि) लागू करूंगा? 2) अब मेरे पास एक ही कमांड के लिए दो या दो से अधिक हैंडलर हैं, मेरे आईओसी कंटेनर कंट्रोलर में इंजेक्ट करने के लिए उन्हें सही तरीके से कैसे सेट करेंगे? 3) क्या मुझे अभी भी आदेशों को संभालने से पहले नियंत्रक में प्रमाणीकरण की जांच करनी चाहिए, उनको जोखिम कम करने के लिए स्वीकार नहीं किया जा रहा है? –

+1

यह दृष्टिकोण मेरे दृष्टिकोण से थोड़ा गंध है, क्योंकि आपने एक ही कमांड के लिए 2 हैंडलर परिभाषित किए हैं। मुझे लगता है कि आदेश जारी होने पर उस समय ऑथ चेक किया जाना चाहिए। कम से कम asp.net mvc के साथ मेरे पास एक प्राधिकरण फ़िल्टर होगा (जो शायद वेब एपीआई के साथ भी काम करेगा)। यह वरीयता का मामला है। @LuizDamim कम से कम मेरी ServiceBus (जो मैंने हाल ही में लिखा था) जब स्वत: विन्यास और शायद सेवा बस आप उपयोग कर रहे साथ ही इस विकल्प है कर कुछ प्रकार की अनदेखी करने का विकल्प है। – MikeSW

+0

@LuizDamim 1) लॉगिंग कमांड हैंडलर के रूप में नहीं किया जाना चाहिए, मेरा मतलब है कि कोई संदेश हैंडलर लॉगर निर्भरता ले सकता है। विभिन्न उद्देश्यों के साथ 2 palces में प्रमाणीकरण किया जाता है: आपके पास नियंत्रक स्तर और व्यापार नियम सत्यापन पर इनपुट सत्यापन किया जाता है जो डोमेन ऑब्जेक्ट द्वारा स्वयं किया जाता है। 3) एएसपीएनटी एमवीसी के साथ मैं कहूंगा कि उपयोगकर्ता को उस कार्रवाई तक नहीं पहुंचना चाहिए यदि उसे उस आदेश को जारी करने का अधिकार नहीं है। – MikeSW

4

दृश्य में यह सत्यापन करने के लिए यह अच्छा यूआई है, इसलिए उपयोगकर्ता गलती से इसे क्लिक नहीं करेगा। मैं नियंत्रक को 'वास्तविक' सत्यापन का सत्यापन करता हूं, क्योंकि वहां कमांड बनाया गया है।यदि किसी उपयोगकर्ता के पास अधिकार नहीं हैं, तो उसे कमांड (या उस क्रिया तक पहुंचने) में सक्षम नहीं होना चाहिए।

मुझे लगता है कि हैंडलर में जांच डाल थोड़ा overzelous है, क्योंकि यह अपनी जिम्मेदारी प्राधिकरण करने के लिए नहीं है और जैसा नहीं है कि हैंडलर सीधे एक उपयोगकर्ता द्वारा पहुंचा जा सकता।

+1

यह किसी अन्य सेवा के साथ डोमेन का पुन: उपयोग करने की अनुमति देने के लिए कमांड हैंडलर में प्राधिकरण जांच के लायक होगा। एक उदाहरण के रूप में, एएसपी.NET वेब एपीआई का उपयोग कर एक एपीआई प्रदान करना। आप एक कमांड हैंडलर सजावट बना सकते हैं जिसे प्रत्येक कमांड हैंडलर से पहले 'स्वचालित रूप से' प्राधिकरण सेवा को कॉल करने के लिए ऑपरेशन के रूप में आदेश के साथ प्राधिकरण सेवा को कॉल करने के लिए बुलाया जाता है। –

+0

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

+0

@ बेनस्मिथ असल में एएसपीनेट एमवीसी फिल्टर के समान, पूर्व और पोस्ट कमांड हैंडलर क्रियाओं का समर्थन करने के लिए सेवा बस के लिए यह एक बुरा विचार नहीं है। – MikeSW

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

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