我们曾经遇到过这种情况。
这里有两个解决方案。但我并不是很喜欢它们。
@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" />
第二种方法是使用Aspect。创建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 {
Method method = ((MethodSignature)joinPoint.getMethodSignature()).getMethod();
}
}
@RequestMapping(value="/api/entry", method=RequestMethod.POST)
@ResponseBody
@Protector
public Entry save(@Valid @RequestBody Entry entry, Principal principal) {
this.entryService.save(entry);
return entry;
}
如果你使用aspect,你可以在运行时拥有更多的控制权
此外,请参考这个链接
@PreAuthorize
。对于其他遇到类似问题的人来说,保护请求体对我来说有些复杂,但我已经能够连接一些服务并创建一个bean。当调用bean实例时,EL会稍微改变。例如:@PreAuthorize("@decision.isOK(#entry.blog.id, principal)")
。 - Josh Johnson@PreAuthorize
正是为此目的而设,而 @Aspect 则更为通用 :) - Elbek@PreAuthorize("Decision.isOK(#entry, #principal)")
而不是@PreAuthorize("Decision.isOK(entry, principal)")
。 - Saad Benbouzid