我应该如何设计端点以根据spring中的用户角色返回不同的模型

kkbh8khc  于 2021-09-29  发布在  Java
关注(0)|答案(2)|浏览(330)

假设我有两个模型类-用户和演示,它们看起来像这样:

@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得到答案,所以我被卡住了。。。任何帮助都将不胜感激,谢谢!

to94eoyn

to94eoyn1#

您不必将用户名传递给控制器方法。在spring中,当前经过身份验证的用户可以通过许多不同的机制获得。检索当前经过身份验证的主体的最简单方法是通过对 SecurityContextHolder 这样地:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();

所以您可以重构您的方法 getAllPresentations() 在服务类中接受 username 作为参数,然后可以通过传递来加载用户 username 并返回该用户的演示文稿。

bmvo0sr5

bmvo0sr52#

做你想做的事情的一个方法是使用 @PostFilter 过滤器注解 List<Presentation> 已验证用户拥有的或已验证用户是否具有角色 ADMIN 这样地:

@GetMapping
@PostFilter("filterObject.user.username == authentication.principal.username or hasRole('ADMIN')")
public List<PresentationDTO> getAllPresentations() {
    return presentationService.getAllPresentations();
}

相关问题