내 REST 인터페이스 용으로 Spring-data-rest를 사용하고 노출 된 엔드 포인트에서 맞춤형 보안 검사를 구현했습니다. 모든 것이 잘 작동하지만 지금은 사소한 시나리오를 겪었습니다. 스프링 데이터 나머지가이 문제를 해결할 수 있는지 궁금합니다. 주기를 가져 오는 경우스프링 데이터 나머지 중첩 된 엔티티에 대한 findBy securityCheck
@Entity
public class Cycle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "unique_cycle_id")
private long id;
@Column(name = "user_id")
private long userId;
...
@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "cycles_records", joinColumns = @JoinColumn(name = "unique_cycle_id"),
inverseJoinColumns = @JoinColumn(name = "unique_record_id"))
private List<Record> records;
}
@Entity
public class Record {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "unique_record_id")
private long id;
...
}
, 내가 확인 로그인 한 사용자의 내주기 엔티티의 userId
와 동일한 ID를 가지고
나는 다음과 같은 모델을 가지고있다.
@Slf4j
@Component
public class SecurityCheck {
public boolean check(Record record, Authentication authentication) {
log.debug("===Security check for record===");
if (record == null || record.getCycle() == null) {
return false;
}
return Long.toString(record.getCycle().getUserId()).equals(authentication.getName());
}
public boolean check(Cycle cycle, Authentication authentication) {
if (cycle == null) {
return false;
}
return Long.toString(cycle.getUserId()).equals(authentication.getName());
}
}
을하지만 지금은 기록을 위해 유사한 보안 검사를 구현하기 위해 노력하고 있습니다 :
나는이 같은 cystom 보안 검사를 시행하고있다. 따라서 주어진주기에 대한 레코드를 가져올 때 사이클의 userId가 인증 객체의 id와 일치하는지 확인해야합니다.
나는이 내 RecordRepository에 다음과 같은 방법
@Repository
public interface RecordRepository extends JpaRepository<Record, Long> {
@PreAuthorize("hasRole('ROLE_ADMIN') OR @securityCheck.check(???, authentication)")
Page<Record> findByCycle_Id(@Param("id") Long id, Pageable pageable);
}
그것이 내가이 securityCheck 내부에이 방법으로 질의하고있는 ID를 가지는 사이클 내부 사용자 ID에 액세스 할 수 있습니까? 그렇지 않다면이 기능을 구현하는 올바른 Spring의 방법은 무엇입니까?
죄송합니다. 제 질문은 명확하지 않습니다. 추가 설명이 필요한지 알려주세요.
편집 : 나는 포스트 필터에서 반환 된 페이지에 액세스하여 빠르고 더러운 솔루션을 발견했습니다. 반환 된 배열이 비어있을 때 내가 제대로 이해했다면 단점은
@PostAuthorize("hasRole('ROLE_ADMIN') OR @securityCheck.check(returnObject, authentication)")
Page<Record> findByCycle_Id(@Param("id") Long id, Pageable pageable);
public boolean check(Page<Record> page, Authentication authentication) {
log.debug("===Security check for page===");
if (!page.hasContent()) {
return true;
}
long userId = page.getContent().get(0).getCycle().getUserId();
return Long.toString(userId).equals(authentication.getName());
}
당신이있는 거 프로젝트가 나에게 흥미 보인다. 그것은 github에 있습니까? 나는 불행히도이 질문에 대한 답을 가지고 있지 않지만, 나는 나중에 그것을 보길 원합니다. 필자는 커스터마이징이 필요할 때마다 스프링 데이터를 사용하지 않으려 고했다. 왜냐하면 필자가지지하는 프레임 워크보다 부담이 많았 기 때문이다. 어쩌면 프로젝트가 내 마음을 바꿀 수 있고 새로운 아이디어를 보여줄 수 있습니다 :) –
불행히도이 특정 프로젝트는 opensource가 아니지만 메시지를 보내려는 경우 제 솔루션을 공유하게되어 기쁩니다. 내 문제에 대한 더러운 해결책을 찾았지만 나는 아직도 좀 더 탄력적 인 방법이 있기를 바란다. (나의 우스꽝스러운 질문을 보라). – Smajl