0

我对 Spring Security Framework 很陌生,这里有一个小问题要解决。

我已经设法将 @PreAuthorized("hasPermission('#person', Permission) 注释用于服务和控制器方法。这对我来说很好,但这仅适用于整个 Domain 类。

在我的例子中,有一些字段应该显示给用户,尽管他们没有读取这个人的权限。

一个简单的例子:

  1. 用户登录。
  2. 他想访问 Jon Doe 的个人资料页面。
  3. 但是用户没有阅读 Jon Doe 的权利。
  4. 系统应该会注意到用户他没有权限并显示名称,例如:您没有权限从 Jon Doe 读取个人资料。”

这是一个非常简单的例子,用户可以看到更多的字段。

希望你能明白我的要求。

(对不起,我的英语不是那么好。)

编辑

个人控制器

 @RequestMapping("/{id}")
 public String get(@PathVariable("id") Long personId, Model model,HttpSession session) {

    Person person = personService.findById(personId);

    /* DO STUFF HERE */

    return "person.show";
}

人员服务

@PreAuthorize("hasPermission('#personId', <domainClass>, 'read')")
public Person findById(Long personId) {
    return personRepository.findOne(personId);
}
4

1 回答 1

0

@PreAuthorized("hasPermission('#person', Permission)您可以通过完全不使用注释来明确地做到这一点,而是在您的代码中手动进行......但这会部分损害使用 Spring Security 框架的兴趣!

我会建议 :

  • 在服务类层使用@PreAuthorized("hasPermission('#person', Permission)注释=>它应该抛出一个AccessDeniedException不允许用户读取该配置文件
  • AccessDeniedException在调用控制器中添加处理程序。由于在控制器的方法执行期间会抛出异常,因此该处理程序将有机会处理它。从相关服务类调用非受保护方法,该方法仅返回公共字段并转发到一个视图,表明您无权从 Jon Doe 读取配置文件

在该配置中,异常处理程序应采用与原始控制器方法等效的参数来访问:

  • 执行Principal请求
  • 请求配置文件的 ID

但这应该不是问题,因为@RequestMapping除了异常本身之外,异常处理程序可以接受与方法所做的几乎相同的参数。

根据您的编辑,您personId从路径变量中获取,这很难从异常处理程序中获取。因此,在调用受保护的服务方法以在异常处理程序中获取它之前,您应该将其保存为请求属性:

 @RequestMapping("/{id}")
 public String get(@PathVariable("id") Long personId, Model model,HttpSession session, HttpServletRequest request) {

    request.setAttribute("personId", personId);
    Person person = personService.findById(personId);

    /* DO STUFF HERE */

    return "person.show";
} 

@ExceptionHandler(AccessDeniedException.class)
 public ModelAndView accessDeniedHandler(HttpServletRequest request) {
    ModelAndView mav = new ModelAndView("accessDeniedView");
    Long personId = request.getAttribute("personId");
    // populate your model
    return mav;
}
于 2015-04-22T12:26:09.853 回答