8

@RequestBody使用 Spring Security保护安全的正确方法是什么?

例如:AUser可以有多个Blogs,每个都Blog可以有多个Entrys。用户将条目保存到某个博客,请求将如下所示:

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

现在,传入entry有一个Blog,用户可以修改请求并选择其他人的博客,有效地将条目发布到他们的博客。虽然我可以在验证中捕捉到这一点(查询持久层以验证是否Blog属于已登录User),但我觉得这应该由 Spring Security 处理。如果是这样,我该怎么做?

4

1 回答 1

10

我们遇到过这种情况。

这是两个解决方案。我不太喜欢

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

//在这种情况下,Spring 将从 Decision 类调用您的静态 isOk() 方法。它应该返回布尔值。

Spring 为方法注入 Principal 主体授权对象,你不必担心。启用@PreAuthorize注释

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

第二个使用方面。创建方面。

@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

于 2012-09-27T01:02:27.310 回答