【发布时间】:2018-05-28 11:09:26
【问题描述】:
我将 Spring-data-rest 用于我的 REST 接口,并且我已经在暴露的端点上实现了自定义安全检查。一切正常,但现在我遇到了一些不平凡的场景,我想知道 spring data rest 是否能够解决这个问题。
我有以下型号:
@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;
...
}
在获取循环时,我会检查登录用户的 id 是否与我的 Cycle 实体中的 userId 相同。
我已经像这样实施了 cystom 安全检查:
@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());
}
}
但现在,我正在尝试对记录实施类似的安全检查。因此,在获取给定循环的记录时,我需要检查循环的 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 访问循环内的 userId?如果不是,那么实现此功能的正确 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上吗?不幸的是,我没有这个问题的答案,但我很想在当天晚些时候看看。当我需要自定义太多时,我总是放弃使用 Spring Data Rest,因为它对我来说更像是一种负担,而不是一个支持框架。也许你的项目可以改变我的想法并向我展示新的想法:)
-
不幸的是,这个特定项目不是开源的,但如果你想给我发消息,我很乐意分享我的解决方案 :) 我为我的问题找到了一个肮脏的解决方案,但我仍然希望还有更多有弹性的方式(见我更新的问题)......
标签: java spring-boot spring-data-rest