PostAuthorize注解在请求处理器调用的方法上不生效的原因
你的@PostAuthorize注解没生效,核心是两个关键问题:
private方法无法被Spring AOP代理拦截
Spring Security的注解(包括@PostAuthorize)依赖Spring AOP实现,而AOP代理默认只能作用于public修饰的方法。private方法属于类内部私有方法,Spring无法为其生成代理增强,注解里的授权逻辑根本不会被执行。内部直接调用方法绕过了代理
就算把getOrder改成public,当前用this.getOrder(...)的方式调用,也会绕过Spring生成的代理对象,直接调用原始类的方法,同样触发不了@PostAuthorize的逻辑。只有通过代理对象调用方法时,AOP的增强逻辑才会生效。
修复方案
- 将
getOrder方法的修饰符改为public - 避免直接用
this调用,要么把当前类自身注入进来通过代理对象调用,要么把该方法抽离到单独的Service类中,通过依赖注入调用。
修改后的示例代码:
@GetMapping("/read") public String showOrderDetail(Model model, HttpServletRequest request, Principal principal) { String idStr = request.getParameter("id"); var corder = new Corder(); corder.setId(35); if (idStr != null) { Integer id = Integer.parseInt(idStr); // 通过注入的Service代理对象调用方法 corder = orderService.getOrder(id, principal); } model.addAttribute("corder", corder); return "orderDetails"; } // 抽离到独立的Service类,方法设为public @Service public class OrderService { @PostAuthorize("hasRole('ADMIN') || " + "authentication.name == returnObject.username") public Corder getOrder(Integer id, Principal principal) { Corder corder = repository.findById(id).orElseThrow(); User user = userRepository.findById(corder.getUserId()).get(); corder.setUsername(user.getUsername()); return corder; } }
内容的提问来源于stack exchange,提问作者Park JongBum
相关产品推荐
相关产品推荐

