java - Spring 启动: Data access depending on role

标签 java spring-boot spring-security

对于数据仓库中的 REST-API,我需要一些基于角色的数据访问。首先让我们通过一些小例子来阐明需求。我们定义实体 AuthorBook,两者都使用 PagingAndSortingRepository 作为其默认行为。一位作者可以“拥有”多本书,而一本书只能依赖于一位作者。

简化的实体应如下所示:

@Entity
@Table(name = "Author")
public class Author{
    // [..]
    @OneToMany(mappedBy = "author")
    private List<Book> books;
}

@Entity
@Table(name = "Book")
public class Book{
    // [..]
    @ManyToOne
    @JoinColumn(name = "Author_ID")
    private Author author;
}

然后我定义两个角色UserAdmin。通常作者是普通用户,因此授权机制只为角色User添加一个SimpleGrantedAuthority。但有一些特殊的作者还具有 Admin 角色。

当具有User角色的普通作者调用url \books时,他应该只获取他拥有的图书,而具有Admin角色的作者应该获取所有存在的图书。此外,对于具有 User 角色的 PUT/PATCH/DELETE 请求作者,应该只能更新/删除自己的图书,而 Admin 角色则能够对所有图书执行此操作。

我的问题:有没有办法在Controller类中定义一次数据访问?我从 Django-Framework 中知道类似的东西,我可以重写方法 get_queryset() ,该方法为每个“ View ”方法(GET/LIST/CREATE/UPDATE/等)提供了可使用的数据集。我目前存档的方法是在 Controller 中为不同的 API 端点定义方法,然后管理那里的访问。这会导致两个问题:

  • 需要做很多工作来实现 Controller 中的方法
  • 如果您的实体之间有很多依赖关系(我的 dwh 就是这种情况),您可能很容易错过某些端点。因此,我可能有一个端点,每个作者都拥有完全访问权限,无论哪个角色。

我认为这应该是一个常见问题,但我还没有找到常见的解决方案。所以我很感谢每一个建议。

<小时/>

编辑:“安全方法”示例

    @RequestMapping(value = "/dimensionAttributeValues", method = RequestMethod.GET)
    @ResponseBody
    public PagedResources<DimensionAttributeValue> getDimensionAttributeValues(Pageable pageable, PersistentEntityResourceAssembler persistentEntityResourceAssembler) {
        Page<DimensionAttributeValue> result;

        if (SecurityUtils.userHasRole(ADMIN) || SecurityUtils.userHasRole(TIMEMANAGER)) {
            result = dimensionAttributeValueService.getAllDimensionAttributeValue(pageable);
        } else {
            result = dimensionAttributeValueService.getUserDimensionAttributeValue(SecurityContextHolder.getContext().getAuthentication().getName(), pageable);
        }

        PagedResources<DimensionAttributeValue> resources;
        resources = this.toResource(result, persistentEntityResourceAssembler);

        // TODO: Remove dirty Hack!
        Link searchLink = linkTo(DimensionAttributeValueController.class).slash("/dimensionAttributeValues/search").withRel("search");
        resources.add(searchLink);

        return resources;
    }

最佳答案

如果您想在存储库级别执行此操作,Spring Security 可以让您访问存储库中的主体。

无论如何,您都需要为此定义一个自定义查询。

类似于此处描述的内容:https://www.baeldung.com/spring-data-security在第3.2章中

否则,您可以添加服务层并使用@PreAuthorize注释

关于java - Spring 启动: Data access depending on role,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57569809/

相关文章:

java - Spring Boot 不从 application.properties 加载用户名

postgresql - Spring Boot 2.2.2 和 "hibernate.hbm2ddl.auto=(create|create-drop|update|validate)"不工作

java - 在 Spring Security (Spring Boot 2.x) 中,我如何为 @Pre/PostAuthorize 和检查角色提供自己的实现?

java - Spring Security 具有自定义 AuthenticationProvider 自定义用户详细信息和自定义安全上下文

java - 为什么从 AWS SDK 创建客户端会挂起 AWS Lambda

java - 如何以 double 形式而不是字符串形式显示 JTextField

java - 开发产品的不同版本

java - 如何使用@OneToMany 集合进行分页

java - Spring Boot 应用程序无法启动,因为类 org.eclipse.jetty.server.Server 不存在

java - 可以使用任何 JWT token 调用 API