【问题标题】:Is it possible to check permissions on a Spring Controller method without executing it?是否可以在不执行 Spring Controller 方法的情况下检查权限?
【发布时间】:2015-01-28 14:21:55
【问题描述】:

我的 REST API 的 JS 客户端想知道,是否允许查询某个 URL。使用标准注释在控制器方法上配置权限:

@Controller
@RequestMapping("/books")
public class BooksController {

  @RequestMapping("read")
  @Secured("ROLE_READER")
  public ModelAndView read(int id) { ... }

  @RequestMapping("write")
  @Secured("ROLE_WRITER")
  public ModelAndView write(int id, String contents) { ... }
}

@Controller
@RequestMapping("/util")
public class UtilController {

  @RequestMapping("check")
  public String check(String url) {
    //if url is "/books/read" and isUserInRole("ROLE_READER")
    //or url is "/books/write" and isUserInRole("ROLE_WRITER")
    //return "true", otherwise "false"
  }
}

对于只读方法,可以对 JS 客户端进行编程以尝试访问 URL 本身,忽略结果并仅查看状态(200 或 403-Forbidden)。这不是最好的性能,但至少在功能上是正确的。但是对于 write 方法,我认为没有办法解决。希望有一个理智的解决方案来解决这个问题。

附:感谢@Bogdan 的解决方案。这是我需要的方法的全文:

@Autowired
WebInvocationPrivilegeEvaluator evaluator;

@RequestMapping("/check")
public String check(String url, Authentication authentication) {
    return Boolean.toString(evaluator.isAllowed(url, authentication));
}

【问题讨论】:

    标签: java spring security rest spring-security


    【解决方案1】:

    对于您发布的UtilController,您可以使用WebInvocationPrivilegeEvaluator 之类的东西,也许还可以看看authorize tag 的工作原理。

    此外,根据您所做的事情,这样的事情也可以工作:

    @Controller
    @RequestMapping("/books")
    public class BooksController {
    
      @RequestMapping("read")
      @Secured("ROLE_READER")
      public ModelAndView read(int id) { ... }
    
      @RequestMapping("canRead")
      @Secured("ROLE_READER")
      public void canRead() { }
    
      @RequestMapping("write")
      @Secured("ROLE_WRITER")
      public ModelAndView write(int id, String contents) { ... }
    
      @RequestMapping("canWrite")
      @Secured("ROLE_WRITER")
      public void canWrite() { }
    }
    

    您还可以通过以下方式检查多个角色:

    @RequestMapping("canReadOrWrite")
    @Secured({"ROLE_READER", "ROLE_WRITER"})
    public void canReadOrWrite() { }
    
    

    然后您可以检查调用新方法的状态码。

    【讨论】:

    • @Andrew Skiba:我已经在我的答案中添加了一些细节,这是一种更简单的方法,以防这些是您唯一需要执行检查的地方
    • 谢谢,WebInvocationPrivilegeEvaluator 正是我所寻找的。我编辑了 OP 以包含解决方案。
    • 嗨,博德扬。我们正在尝试使用 WebInvocationPrivilegeEvaluator 使用该解决方案,但我们的评估器始终返回 true。即使有 DenyAll 注释。我们认为@autowired 工作不正常,我们总是得到一个简单的 WebInvocationPrivilegeEvaluator 忽略我们的 spring-security 配置。关于如何获得适当的 WebInvocationPrivilegeEvaluator 的任何想法?也许通过 SecurityContextHolder?
    猜你喜欢
    • 2010-11-13
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    相关资源
    最近更新 更多