在我的网络应用程序中,我有2个实体User
和Ad
,其中一个用户可以发布多个广告,而且只有一个用户可以创建一个广告,现在我正在尝试执行安全地删除选项,但它仍然容易受到攻击,用户仍然可以删除不是他的广告的广告,我的意思是他不是所有者。
我所做的方法是在删除ad
之前我验证广告的id
所有者是否等于会话中已关联的人员的id
以及&# 39;工作正常。现在我问的是,如果没有这种验证技巧,我可以采用更好的方法。
广告控制器
@RequestMapping(value="/delete_ad/{id_ad}", method=RequestMethod.GET)
public String doDeleteAd(@PathVariable("id_ad") Long id_ad, RedirectAttributes redirectAttributes) {
Ad ad = adService.findAdById(id_ad);
if (ad == null) {
redirectAttributes.addFlashAttribute("alert", "alert-danger");
redirectAttributes.addFlashAttribute("messageDelete","<strong>Oops !</strong> no Ad founded with that id");
return "redirect:/myads";
}else {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetail = (UserDetails) auth.getPrincipal();
User u = (User) userDetail;
if (ad.getPublisher().getId_user() == u.getId_user()) {
adService.deleteAdById(id_ad);
redirectAttributes.addFlashAttribute("alert", "alert-success");
redirectAttributes.addFlashAttribute("messageDelete", "<strong>Done !</strong> Ad deleted succesfully");
return "redirect:/myads";
}else {
redirectAttributes.addFlashAttribute("alert", "alert-info");
redirectAttributes.addFlashAttribute("messageDelete", "<strong>Opps !</strong> you are not the owner of the ad");
return "redirect:/myads";
}
}
}
并在my_ads
视图中,我为每个广告添加了以下链接
<a href="delete_ad/${ad.id_ad }" class="btn btn-sm btn-danger" >delete</a>
答案 0 :(得分:0)
通常,您是正确的,因为在某些时候您必须手动检查当前经过身份验证的用户是否有权删除该记录。
我认为在控制器中使用这个逻辑并不是最好的地方。如果您希望在应用程序的其他位置重用删除服务会发生什么?我建议将检查放入服务层并在用户无权访问时抛出异常 - 否则您甚至可以使用JPA lifecycle callbacks将其移入@Entity
类本身。例如在Ad
类中:
@PreRemove
void checkPermissions() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetail = (UserDetails) auth.getPrincipal();
User u = (User) userDetail;
if( this.getPublisher().getId_user() != u.getId_user() ) {
throw new SomeCustomNotAuthorizedException("User can't delete record");
}
}
然后你可以在Controller中捕获它并采取任何必要的操作。一个缺点是你没有“按id删除”方法,你必须从数据库加载对象然后在实例上调用delete。