2011-10-03 16 views
13

पर ओवरराइड नहीं किया जा सकता है। मैं @PreAuthorize एनोटेशन के साथ नियंत्रक की रक्षा करने की कोशिश कर रहा हूं और विभिन्न व्यवहारों को अलग-अलग @PreAuthorize के साथ एनोटेट करके उस व्यवहार को ओवरराइड करने का प्रयास कर रहा हूं। समस्या यह है कि, वसंत पहले विधि एनोटेशन का मूल्यांकन कर रहा है (अनुदान पहुंच) और फिर कक्षा एनोटेशन का मूल्यांकन कर रहा है (पहुंच से इनकार करता है)।स्प्रिंग सिक्योरिटीज @ प्राइवॉर्डेनाइजेशन टाइप स्तर पर विधि स्तर

क्या इस आदेश को रिवर्स करने का कोई तरीका है? मैं अभी तक इसे समझ नहीं पाया।

संपादित करें:

@PreAuthorize("isAnonymous()") 
@RequestMapping(value = "/create", method = RequestMethod.GET) 
public String renderCreateEntity(ModelMap model) { 
    return userService.renderCreateEntity(model); 
} 

इस नियंत्रक तथापि के लिए मानक, केवल पूरी तरह से प्रमाणीकृत उपयोगकर्ताओं अनुमति देने के लिए किया जाना चाहिए:

विधि स्तर पर, मैं केवल गैर पंजीकृत उपयोगकर्ताओं को पहुंच प्रदान करना चाहते हैं:

@Controller 
@RequestMapping(value = "/user") 
@PreAuthorize("isFullyAuthenticated()") 
public class UserController { [...] } 

जब डिबग-कदम एप्लिकेशन के माध्यम से, मुझे लगता है कि isAnonymous() पहले मूल्यांकन किया जाता है और उसके बाद isFullyAuthenticated() इस प्रकार जिसके परिणामस्वरूप पहुंच के अनुदान में और तुरंत पहुंच को अस्वीकार कर दिया।

+0

स्प्रिंग सुरक्षा का कौन सा संस्करण आप उपयोग कर रहे हैं? – beny23

+0

सब कुछ वसंत 3.0.5 है .RELEASE – chzbrgla

उत्तर

11

आपके सभी उत्तरों के लिए धन्यवाद। हालांकि उत्तर कुछ अलग था :)

मैंने इसे यहां किसी अन्य समस्या के मामले में रखा है।

मैंने @InitBinder एनोटेटेड विधि में एक कस्टम सत्यापनकर्ता पंजीकृत किया है। नियंत्रक पर अनुरोध विधि कॉल के बाद यह बाध्यकारी विधि कहा जाता है। और चूंकि इस बाध्यकारी विधि को @PreAuthorize के साथ एनोटेट नहीं किया गया था, इसलिए अनुरोध अस्वीकार कर दिया गया था।

@InitBinder 
@PreAuthorize("permitAll") 
public void initBinder(WebDataBinder binder) { 
    binder.setValidator(validator); 
} 

और फिर, विधि मेरी ओपी की उम्मीद की तरह का मूल्यांकन से कॉल:

समाधान इस तरह बंधन विधि टिप्पणी करने के लिए किया गया था।

5

समस्या यह नहीं है कि आपको अनुदान और अस्वीकार करने का आदेश बदलने की आवश्यकता है। समस्या यह आसान है कि विधि स्तर एनोटेशन वर्ग स्तर एनोटेशन ओवरराइड करें।

PrePostAnnotationSecurityMetadataSource Java Doc:

एनोटेशन वर्ग या विधियों, और विधि-विशेष एनोटेशन पर निर्दिष्ट किया जा सकता प्राथमिकता दी जाएगी।

इस तर्क का ठोस कार्यान्वयन PrePostAnnotationSecurityMetadataSource वर्ग findAnnotation विधि में किया गया है। (दुर्भाग्य से यह विधि निजी है।)

तो यदि आप PrePostAnnotationSecurityMetadataSource के कोड पर नज़र डालते हैं, तो आप अपना खुद का MethodSecurityMetadataSource लिख सकते हैं, तो आप देखेंगे कि यह कितना आसान है।

लेकिन अंत में एक चेतावनी: अंत: कठिन कार्य विधि को फिर से लिखना नहीं है, कठिन कार्य सुरक्षा प्रणाली में नए MethodSecurityMetadataSource को "इंजेक्ट" करना है। मुझे विश्वास है कि आप वसंत सुरक्षा नेमस्पेस कॉन्फ़िगरेशन के साथ ऐसा नहीं कर सकते हैं, इसलिए आपको स्पष्ट बीन घोषणा द्वारा वसंत सुरक्षा नामस्थान को प्रतिस्थापित करने की आवश्यकता है।

+0

मैं कक्षा स्तर एनोटेशन को ओवरराइड करने के लिए विधि स्तर एनोटेशन वास्तव में _WANT_ करता हूं। लेकिन विधि स्तर एनोटेशन का मूल्यांकन पहले और कक्षा स्तर दूसरे का मूल्यांकन किया जाता है ताकि कक्षा स्तर एनोटेशन वास्तव में विधि की एनोटेशन को ओवरराइड कर सके। मैं अपने प्रश्न में कुछ उदाहरण संपादित करूंगा। – chzbrgla

+0

मेरे परीक्षण से, यह अब और सत्य नहीं है। यदि आपके पास कक्षा स्तर और विधि स्तर सुरक्षा एनोटेशन (या तो @ सुरक्षित या @ प्राधिकृत) है, तो वे दोनों दौड़ते हैं। यदि विधि स्तर एनोटेशन अधिक प्रतिबंधित है, तो यह ठीक है। यदि यह कम प्रतिबंधक है, तो यह काम नहीं करता है। मैंने अपने कम प्रतिबंधक तरीकों को दूसरे नियंत्रक में विभाजित कर दिया। –

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