Spring Protection @RequestBody

What is the right way to protect @RequestBodywith Spring Security?

For example: A Usermay have several Blog, and each Blogmay have several Entrys. The user goes to save the entry to a specific blog, and the request will look like this:

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

Now the inbox Entryhas Blog, the user could process the request and select another blog, effectively posting an entry on his blog. Although I could catch it when checking (ask for a persistence level to make sure it Blogbelongs to a registered one User). I believe this should be handled by Spring Security. If so, how do I do this?

+5
source share
1 answer

We had such a situation.

Here are two solutions. I did not like much

@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;
} 

or

@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;
    }

// In this case, Spring will call your static isOk () method from the Decision class. It should return a boolean value.

Spring introduces the main basic permitted object for the method, you do not need to worry about it. Enable annotation @PreAuthorizewith

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

The second use of the aspect. Create an aspect.

@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;
} 

If you have an aspect, you can have more ownership at runtime.

Also see this ulr

+6
source

All Articles