>

데이터웨어 하우스 내의 REST-API에는 역할 기반 데이터 액세스가 필요합니다. 먼저 몇 가지 작은 예를 통해 요구 사항을 명확하게 설명하겠습니다. 우리는 엔티티 Author 를 정의  그리고 Book , 둘 다 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;
}

그런 다음 User 의 두 가지 역할을 정의합니다.  그리고 Admin . 일반적으로 저자는 일반적인 사용자이므로 권한 부여 메커니즘은 SimpleGrantedAuthority 만 추가합니다.  역할 User . 그러나 Admin 역할을하는 특별한 저자가 있습니다. .

User 역할을 가진 일반 저자 인 경우  URL \books 를 호출 , 그는 자신이 소유 한 책만 가져와야하고, 역할 Admin 를 가진 저자  존재하는 모든 책을 가져와야합니다. 또한 PUT/PATCH/DELETE   User 로 저자 요청  역할은 자신의 책만 업데이트/삭제할 수 있어야하며, Admin 는  role은 모든 책에 대해이 작업을 수행 할 수 있습니다.

내 질문 : Controller 에서한 번데이터 액세스를 정의 할 수있는 방법이 있습니까  수업? 나는 Django-Framework 에서 그런 것을 알고 여기서 get_queryset() 메소드를 대체 할 수 있습니다. 모든 "보기"-방법 (GET/LIST/CREATE/UPDATE/etc.)에 대해 작업 할 데이터 세트를 제공합니다. 현재 이것을 보관하는 방법은 다른 API 엔드 포인트에 대해 컨트롤러에서 메소드를 정의하고 액세스를 관리하는 것입니다. 두 가지 문제가 발생합니다 :

  • 컨트롤러에서 메소드를 구현하기위한 많은 작업
  • 엔터티간에 많은 종속성이있는 경우 (이 경우 내 경우)일부 엔드 포인트를 쉽게 놓칠 수 있습니다. 결과적으로 어떤 역할에 관계없이 모든 작성자에게 모든 권한이있는 엔드 포인트가있을 수 있습니다.

이것은 일반적인 문제 여야한다고 생각하지만 아직 일반적인 해결책을 찾지 못했습니다. 모든 조언에 감사드립니다.

<시간>

수정 :"보안 된 방법"의 예

   @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;
    }

  • 답변 # 1

    저장소 수준에서 수행하려면 스프링 보안을 통해 리포지토리의 보안 주체에 액세스 할 수 있습니다.

    어쨌든 사용자 정의 쿼리를 정의해야합니다.

    여기에 설명 된 것과 유사한 것 : https://www.baeldung.com/spring-data-security 3.2 장

    그렇지 않으면 서비스 계층을 추가하고 @PreAuthorize 를 사용할 수 있습니다  주석

  • 답변 # 2

    저장소 호출에 where 조건을 추가하여 역할별로 결과를 필터링 할 수 있습니다. JpaSpecificationExecutor의이 메소드를 확인하십시오 :

    Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
    
    

    예 (지금 테스트 할 수는 없지만 올바른 방향으로 안내해야합니다) :

    import static org.springframework.data.jpa.domain.Specifications.where;
    ..
    Specification<Book> roleFilter = (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("role"), "Admin");
    Page<Book> page = this.yourRepository.findAll(where(roleFilter), pageable);
    
    

  • 이전 mongodb upsert 카운터가 실제 변경 사항을 반영하지 않는 이유는 무엇입니까?
  • 다음 microservices - Docker Compose에서 프론트 엔드 및 SSR 서비스 분할