即使在用户已经登录后,还是通过spring acl插件重定向到登录页面?

时间:2016-11-17 08:12:08

标签: grails spring-security

我使用spring acl插件来添加对象的权限,以便拥有一个对象的用户无法访问另一个用户拥有的对象。

在许多控制器更新方法中,我必须检查执行操作的用户是否有写权限,因此第一行通常是

myAclService.hasWritePermission(id, Event)

如果未找到权限,此方法将抛出访问被拒绝的异常。

现在我的困境是,即使在用户登录并且控制器方法被命中后,用户也常常被重定向到登录页面。这是Spring安全插件中的一个弱点,它导致了这种行为。我想知道如果用户已经登录,是否可以防止这种重定向?是否有其他人使用spring插件有同样的问题?我感谢任何帮助!谢谢!

1 个答案:

答案 0 :(得分:0)

您可以为AccessDeniedException添加自定义处理程序。有更多方法可以做到这一点。一种方法:通过使用@ControllerAdvice注释类并添加异常处理方法,为所有控制器创建全局处理程序。

 @ExceptionHandler(AccessDeniedException.class)
 public void handleAccessDenied() {
    if (SecurityContextHolder.getContext().getAuthentication() != null &&
       SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
       //when Anonymous Authentication is enabled
       !(SecurityContextHolder.getContext().getAuthentication() 
          instanceof AnonymousAuthenticationToken) ) {
          // do nothing
       } else {
          throw new MyCustomException();
       }
  }

  @ExceptionHandler(MyCustomException.class)
  public String handleAccessDeniedForNotLoggedInUser() {
    return "redirect:/login";
  }

另外我相信在SpEL中使用ACL表达式会更具可读性。 如果按照Spring准则设置ACL,则可以使用@PreAuthorize("hasPermission(#event, 'WRITE')")之类的表达式来注释控制器方法,我相信Spring会默默地使用这些异常并且不会发生重定向。