Jsp 删除不是我的项目

Jsp 删除不是我的项目,jsp,spring-mvc,spring-boot,spring-security,Jsp,Spring Mvc,Spring Boot,Spring Security,在我的web应用程序中,我有两个实体User和Ad,其中一个用户可以发布多个广告,一个广告可以仅由一个用户创建,现在我正在尝试安全地执行删除选项,但它仍然容易受到攻击,并且用户仍然可以删除一个不是他的广告的广告,我的意思是他不是所有者。 我所做的方法是,在删除ad之前,我验证该ad的id所有者是否与会话中连接的人的id相等,并且工作正常。现在我在问,如果没有验证技巧,是否有更好的方法可以遵循 广告控制器 @RequestMapping(value="/delete_ad/{id_ad}", me

在我的web应用程序中,我有两个实体
User
Ad
,其中一个用户可以发布多个广告,一个广告可以仅由一个用户创建,现在我正在尝试安全地执行删除选项,但它仍然容易受到攻击,并且用户仍然可以删除一个不是他的广告的广告,我的意思是他不是所有者。 我所做的方法是,在删除
ad
之前,我验证该ad的
id
所有者是否与会话中连接的人的
id
相等,并且工作正常。现在我在问,如果没有验证技巧,是否有更好的方法可以遵循

广告控制器

@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";
            }
        }

    } 

一般来说,您是正确的,因为在某些时候,您必须手动检查当前经过身份验证的用户是否具有删除记录的权限

我认为在控制器中使用这种逻辑并不是最好的选择。如果希望在应用程序中的其他位置重用删除服务,会发生什么情况?我建议将检查放入服务层,如果用户没有访问权限,则抛出异常,或者您甚至可以使用将其移动到
@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");
    }
}

然后,您可以在控制器中捕捉到这一点,并采取任何必要的操作。一个缺点是不能使用“deletebyid”方法,必须从数据库加载对象,然后在实例上调用delete

一般来说,您是正确的,在某个时候,您必须手动检查当前经过身份验证的用户是否有删除记录的权限

我认为在控制器中使用这种逻辑并不是最好的选择。如果希望在应用程序中的其他位置重用删除服务,会发生什么情况?我建议将检查放入服务层,如果用户没有访问权限,则抛出异常,或者您甚至可以使用将其移动到
@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");
    }
}

然后,您可以在控制器中捕捉到这一点,并采取任何必要的操作。一个缺点是不能使用“deletebyid”方法,必须从数据库加载对象,然后在实例上调用delete

你也可以考虑使用散列ID,以便前端没有人能从DB中看到ID,但是这将与你已经使用的东西一起使用。implemented@BenLonsdale你的意思是我应该在我的模式中添加另一个令牌字段,以基于该令牌执行删除!!不是吗t@saul-你所拥有的一切都很好,而且是传统的方式。采取一个ID并验证它在执行该操作之前绑定到该用户。您还可以考虑使用散列ID,以便前端的任何人实际上都可以从DB中看到ID,但是这将与您已经使用的ID一起使用。implemented@BenLonsdale您的意思是我应该在模式中添加另一个令牌字段来执行删除操作基于这个标记!!不是吗t@saul-你所拥有的一切都很好,而且是传统的方式。在执行操作之前,获取一个ID并验证它是否绑定到该用户。