I am using Spring -data-rest for my REST interface and I have implemented custom security checks on my open endpoints. Everything works fine, but now I came across some non-trivial scenario, and I wonder if this spring resource will be able to solve this issue.
I have the following model:
@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;
...
}
When retrieving the loop, I verify that the logged in user has the same identifier as userId
in my loop object.
I implemented cystom security check as follows:
@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());
}
}
But now I am trying to perform a similar security check for records. Therefore, when retrieving records for a given loop, I need to verify that the userId loop matches the identifier in the authentication object.
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);
}
userId , securityCheck? , spring ?
, . , .
EDIT:
, . , , , ( )
@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());
}