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

Posted

技术标签:

【中文标题】是否可以在不执行 Spring Controller 方法的情况下检查权限?【英文标题】:Is it possible to check permissions on a Spring Controller method without executing it? 【发布时间】: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));

【问题讨论】:

【参考方案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?

以上是关于是否可以在不执行 Spring Controller 方法的情况下检查权限?的主要内容,如果未能解决你的问题,请参考以下文章

Joomla 2.5 组件

JMeter元件详解之 Include Controlle 包含控制器

是否可以在不使用临时文件的情况下在批处理文件中嵌入和执行 VBScript?

在不使用 spring-boot 执行器的情况下将来自 spring 应用程序的指标公开给 prometheus

是否可以在不使用 LoadLibrary 的情况下将函数“复制”到另一个进程中并在线程中执行它?

在不启动服务器的情况下使用 Spring 应用程序属性 [重复]