假设我有两个模型类-用户和演示,它们看起来像这样:
@Entity
public class Presentation {
@Id
private Long id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
@Entity
public class User implements UserDetails {
@Id
private Long id;
private String username;
private String name;
private String surname;
private String password;
@Enumerated(EnumType.STRING)
private Role role;
}
正如您所看到的,我在presentation类中为用户提供了一个单向Map。我的端点如下所示:
@RestController
public class PresentationController {
@GetMapping("/{presentationId}")
public PresentationDTO getPresentation(@PathVariable Long presentationId) {
return presentationService.getPresentationById(presentationId);
}
@GetMapping
public List<PresentationDTO> getAllPresentations() {
return presentationService.getAllPresentations();
}
}
现在我的问题是,如何更改getallpresentations()以返回角色为“user”的用户拥有的演示文稿,并返回角色为“admin”的用户的所有演示文稿?我知道我可以使用不同的Map(如/admin/presentations)创建一个单独的端点,并添加@preauthorize(hasrole(“admin”)),但这里有一个棘手的部分。对于getallpresentations()端点,每个经过身份验证的用户都应该获取自己的演示文稿,我如何知道我必须为哪个用户返回他的演示文稿?也许我可以获取用户名作为参数,但这可能很危险,因为他可以提交任何他想要的用户名,并为该用户获取演示文稿。我对spring security了解不多,我甚至不知道该问什么问题才能让google得到答案,所以我被卡住了。。。任何帮助都将不胜感激,谢谢!
2条答案
按热度按时间to94eoyn1#
您不必将用户名传递给控制器方法。在spring中,当前经过身份验证的用户可以通过许多不同的机制获得。检索当前经过身份验证的主体的最简单方法是通过对
SecurityContextHolder
这样地:所以您可以重构您的方法
getAllPresentations()
在服务类中接受username
作为参数,然后可以通过传递来加载用户username
并返回该用户的演示文稿。bmvo0sr52#
做你想做的事情的一个方法是使用
@PostFilter
过滤器注解List<Presentation>
已验证用户拥有的或已验证用户是否具有角色ADMIN
这样地: