假设使用Java 8和Spring Boot 2,我有一个像下面这样的最小RESTful控制器...
@RestController
class MyController {
@Autowired
private PostService service;
@GetMapping
public Post get() {
return service.getLatest();
}
}
我已经使用Spring Security模块成功保护了此路由。现在,我只允许资源所有者访问此资源。对于资源所有者,我的意思是创建者或简单地说:
Post myPost = new Post();
...
myPost.getCreator().equals(currentUser); // Should be true when access is granted
我发现了很多有关基于角色的访问的信息,但几乎没有用于检查所有权的信息……当然,我可以在控制器中放置if语句并抛出异常,但是我打算使用类似Spring的基于表达式的访问控制之类的东西。
还有其他想法吗?有人对资源的所有权检查有一个好主意或示例吗?
对于简单的get操作,您只需返回链接到当前登录用户的帖子即可
@GetMapping
public Post getPost(Authentication authentication) {
return service.getPostByUser(authentication.getName());
}
要更新现有帖子,您可以在PreAuthorize中检查创建者是否是登录用户。authentication.getName()在我的示例中返回一封电子邮件
@PutMapping
@PreAuthorize("#post.getCreator() == authentication.getName()")
public void update(@RequestBody Post post, Authentication authentication) {
service.updatePost(post);
}
@Component方法的基本示例
@Autowired
private CreatorCheck creatorCheck;
@PutMapping
@PreAuthorize("@creatorChecker.check(#post,authentication)")
public void update(@RequestBody Post post, Authentication authentication) {
service.updatePost(post);
}
和组件。可以扩展以检索原始帖子并检查该创建者。
@Component
public class CreatorCheck {
public boolean check(Post post, Authentication authentication) {
return post.getCreator().equals(authentication.getName());
}
}
但这意味着客户正在请求中设置帖子的创建者,对吗?如何防止它操纵创作者?假设使用自己的ID授予访问权限...或者对于DELETE请求,没有给出DTO /有效载荷作为参数...
您可以编写另一个@Component公共CreatorChecker类来处理检查。@PreAuthorize(“ @ creatorChecker.check(#post,authentication)”)在此组件中,您从数据库检索帖子并检查创建者service.getPostId()。getCreator()== authentication.getName()那样
该组件在哪里使用?作为过滤器链的一部分?这是一个普通的方法吗?我什么都没发现……但是似乎是一个有趣的解决方案
它将与某些默认值(如hasRole('FOO'))以相同的方式进行求值,因为它只是一个需要求值的表达式。 春季文件链接
那是我最喜欢的解决方案...我找到了一个有关使用外部组件进行授权的基本示例。您可以更新您的答案,以便我接受吗?