控制用户更改对象的权限

问题描述 投票:0回答:1

想象有一个用户,他有一个为他发出的特定订单。 用户决定“释放”它并拉取 REST API 句柄:

@PreAuthorize("hasRole('USER') || hasRole('ADMIN')")
@PatchMapping(path = "/setFree", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<OrderDTO> setFree(@RequestParam(name = "id") int id) {
    final var order = this.orderService.findById(id).orElseThrow(() -> new OrderNotFoundException(id));
    if (order.getStatus() == OrderStatus.FREE.getId())
        return ResponseEntity.badRequest().build();

    final var free = this.orderService.setFree(order);
    return ResponseEntity.ok(this.modelMapper.map(free, OrderDTO.class));
}

具有 USER 或 ADMIN 角色的授权用户可以访问此句柄。 问题!在这种情况下,什么会阻止具有 USER 角色的用户为其他用户发布订单。 如何验证这一点?这样用户就只能更改那些“允许”他或与他相关的对象的状态? 在安全上下文中获取当前用户并检查他的

"SpringSecurityHolder"#getId() == order#getUserId();
?但这太原始了。如何正确实施此类验证?

java spring-boot spring-security user-permissions
1个回答
0
投票

@PreAuthorize
允许您使用 SpEL 来引用执行授权检查的 bean 方法。因此您可以定义一个 bean 来进行此类检查,例如:

@Service
public class AuthzService {


    public boolean isAllowFreeOrder(int orderId){
       
      //access the order and current user infomration for the authrrization check
      //return true if it is allow. otherwise , return false
    }  
}

在此方法中,您可以从存储库获取订单并检查其所需的状态。要获取当前用户信息,这里有一些您可能会觉得有用的代码片段:

Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
AppUser user =  (AppUser) currentUser.getPrincipal();


List<GrantedAuthority> userRoles =  = currentUser.getAuthorities()
boolean hasUserRole =  userRoles.stream().map(GrantedAuthority::getAuthority).anyMatch(a->a.equals("ROLE_USER"));
boolean hasAdminRole =  userRoles.stream().map(GrantedAuthority::getAuthority).anyMatch(a->a.equals("ROLE_ADMIN"));

我假设

AppUser
是您在身份验证过程中自定义的用户对象。

最后配置

@PreAuthorize
以使用此方法进行检查:

@PreAuthorize("@authzService.isAllowFreeOrder(#id)")
@PatchMapping(path = "/setFree")
public ResponseEntity<OrderDTO> setFree(int id) {
   
}
© www.soinside.com 2019 - 2024. All rights reserved.