2012-09-26 7 views
5

स्प्रिंग सिक्योरिटी के साथ @RequestBody को सुरक्षित करने का सही तरीका क्या है?स्प्रिंग सिक्योरिंग @RequestBody

उदाहरण के लिए: एक User कई Blog रों हो सकता है और प्रत्येक Blog कई Entry रों हो सकता है। एक उपयोगकर्ता एक निश्चित ब्लॉग पर एक प्रविष्टि को बचाने के लिए चला जाता है और अनुरोध इस तरह में आ जाएगा:

@RequestMapping(value="/api/entry", method=RequestMethod.POST) 
@ResponseBody 
public Entry save(@Valid @RequestBody Entry entry) { 
    this.entryService.save(entry); 
    return entry; 
} 

अब, भेजे entry एक Blog है, उपयोगकर्ता अनुरोध अप मरोड़ा और किसी और के ब्लॉग चुन सकते थे, प्रभावी ढंग से अपने ब्लॉग में प्रवेश पोस्टिंग। हालांकि मैं इसे सत्यापन में पकड़ सकता हूं (BlogUser में लॉग इन से संबंधित है, मुझे लगता है कि यह वसंत सुरक्षा द्वारा संभाला जाना चाहिए। यदि हां, तो मैं ऐसा करने के लिए कैसे जा सकता हूं?

उत्तर

6

हमारे पास इस तरह की स्थिति थी।

यहां दो समाधान हैं। मैं पसंद नहीं आया ज्यादा

@RequestMapping(value="/api/entry", method=RequestMethod.POST) 
@ResponseBody 
@PreAuthorize("#entry.author.name == principal.name)" 
public Entry save(@Valid @RequestBody Entry entry, Principal principal) { 
    this.entryService.save(entry); 
    return entry; 
} 

या

@RequestMapping(value="/api/entry", method=RequestMethod.POST) 
    @ResponseBody 
    @PreAuthorize("Decision.isOK(entry, principal)") 
    public Entry save(@Valid @RequestBody Entry entry, Principal principal) { 
     this.entryService.save(entry); 
     return entry; 
    } 

// उस मामले वसंत अपने स्थिर isOk() निर्णय वर्ग से विधि कॉल होगा। यह बूलियन वापस करना चाहिए।

स्प्रिंग इंजेक्ट्स प्रिंसिपल प्रिंसिपल अधिकृत विधि के लिए अधिकृत वस्तु है, आपको इसके बारे में चिंता करने की ज़रूरत नहीं है।

<security:global-method-security pre-post-annotations="enabled" />

दूसरा पहलू का उपयोग के साथ @PreAuthorize एनोटेशन सक्षम करें। पहलू बनाएं

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface Protector { 
} 

@Aspect 
@Component 
public class MyAspect { 
    @Before("@annotation(com.xyz.Protector)") 
    public void before(JoinPoint joinPoint) throws Throwable { 
     //u can get method object from joinPoint object, 
     Method method = ((MethodSignature)joinPoint.getMethodSignature()).getMethod(); 
     //As long as you have Method object you can read the parameter objects (Entry and Principal) with reflection. 
     //So Compare here: If entry.getOwner().getId().equal(principal.getName()) blah blah blah 
    } 
} 

@RequestMapping(value="/api/entry", method=RequestMethod.POST) 
@ResponseBody 
@Protector 
public Entry save(@Valid @RequestBody Entry entry, Principal principal) { 
    this.entryService.save(entry); 
    return entry; 
} 

आप पहलू है, तो आप और अधिक हो सकता है

क्रम

पर मालिक इसके अलावा इस ulr

+1

का उल्लेख 'साथ दोनों दृष्टिकोण मैं सबसे खुश था की कोशिश कर रहा @ PreAuthorize' के बाद। इस पर आने वाले किसी और के लिए, रेक बॉडी को सुरक्षित करना मेरे लिए कुछ जटिल था और मैं कुछ सेवाओं के साथ एक बीन को तार करने में सक्षम था। एक बीन उदाहरण बुलाते समय ईएल थोड़ा बदलता है। उदाहरण: '@PreAuthorize (" @ decision.isOK (# entry.blog.id, प्रिंसिपल) ")' –

+1

मुझे खुशी है कि यह मदद की :) '@ PreAuthorize', इस उद्देश्य के लिए ठीक है, जबकि @Aspect अधिक सामान्य है हूँ:) – Elbek

+0

@PreAuthorize में स्प्रिंग-ईएल से विधि पैरामीटर का जिक्र करना ''' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' @PreAuthorize ("Decision.isOK (#entry, #principal)") '' '' बजाय '' '' @PreAuthorize ("Decision.isOK (प्रवेश, प्रिंसिपल)") '' ''। –