是否可以在不执行的情况下检查 Spring Controller 方法的权限?

And*_*iba 1 java security rest spring spring-security

我的 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"
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

@Autowired
WebInvocationPrivilegeEvaluator evaluator;

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

Bog*_*dan 5

对于UtilController您发布的内容,您可以使用WebInvocationPrivilegeEvaluator 之类的东西,也许还可以查看授权标签的工作原理。

此外,根据你在做什么,这样的事情也可以工作:

@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() { }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Run Code Online (Sandbox Code Playgroud)

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

  • 嗨,博詹。我们正在尝试使用 WebInvocationPrivilegeEvaluator 的解决方案,但我们的评估器始终返回 true。即使使用 DenyAll 注释。我们认为@autowired 工作不正常,我们总是得到一个简单的 WebInvocationPrivilegeEvaluator,它忽略了我们的 spring-security 配置。关于如何获得适当的 WebInvocationPrivilegeEvaluator 的任何想法?也许通过SecurityContextHolder? (2认同)