1

我已经看到许多要求如何处理安全场景的问题,要么都有方法注释(即@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是为了id作为我错过的论点。

4

2 回答 2

1

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

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

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

如果您发现自己经常使用这种技术,请查看Spring Security ACL模块。

于 2013-10-04T13:19:15.273 回答
0

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

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

于 2013-10-04T11:28:16.247 回答