删除不属于我的项目

时间:2017-08-22 11:35:04

标签: jsp spring-mvc spring-boot spring-security

在我的网络应用程序中,我有2个实体UserAd,其中一个用户可以发布多个广告,而且只有一个用户可以创建一个广告,现在我正在尝试执行安全地删除选项,但它仍然容易受到攻击,用户仍然可以删除不是他的广告的广告,我的意思是他不是所有者。 我所做的方法是在删除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>

1 个答案:

答案 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。