在spring MVC + security中拒绝访问特定资源的正确方法是什么?

时间:2013-10-04 08:12:16

标签: spring-mvc spring-security

我已经看到很多问题要求如何处理安全方案,所有问题都有方法注释的解决方案(即@PreAuthorize("hasRole('ROLE_USER')"))或使用切入点。

但是,如果在从数据存储中读取资源之前用户是否具有访问权限,那么该资源是什么?让我们考虑一个有权访问一组客户的用户,可以在/customers/{id}找到这些客户的其余端点。如果用户已被授予读取帐户的访问权限,则只允许用户访问,同样他们也必须有权访问同一端点{。}}。

一种方法是:

POST

我想知道这是否是正确的方法。

更新:调用@RequestMapping(value = "/customers/{id}", method = RequestMethod.GET) public ModelAndView customerPage(String id, HttpServletRequest req, Principal principal) { if (!req.isUserInRole("ROLE_ADMIN") && !cs.accessGranted(id, principal.getName())) { throw new AccessDeniedException("You do not have access to view this custoemr."); } Customer cust = cs.getCustomer(id); if (cust == null) { throw new ResourceNotFoundException("Customer does not exist!"); } ModelAndView mov = new ModelAndView("customers/info"); mov.addObject("customer", cust); return mov; } 意味着accessGranted作为我错过的参数。

2 个答案:

答案 0 :(得分:1)

有一种方法可以继续使用@PreAuthorize注释。您可以直接从SpEL表达式调用bean:

@PreAuthorize("hasRole('ROLE_USER') and !@cs.accessGranted(#principal.getName())")
public ModelAndView customerPage(String id, HttpServletRequest req, Principal principal) {

@cs指的是在应用程序上下文中声明为somwhere的bean id =“cs”。稍后您可以通过删除Principal principal方法参数并直接在SpEL中获取用户名来简化它。

如果您发现自己经常使用此tehnique,请查看Spring Security ACL模块。

答案 1 :(得分:0)

我最喜欢的方法是在方法上使用@Secured注释,该方法采用表示执行方法所需角色的字符串数组。我喜欢这种方法,因为您不仅限于将安全性放在URL模式上。例如,您可以将其添加到Service类中的方法,现在使用该服务的任何Controller都是安全的。

另一种常见方法是在Spring Security XML文件中包含URL过滤器。我忘记了确切的语法,但您基本上设置了与URL匹配的过滤器,并指出需要哪些角色。