我已经看到很多问题要求如何处理安全方案,所有问题都有方法注释的解决方案(即@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
作为我错过的参数。
答案 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匹配的过滤器,并指出需要哪些角色。