Is it possible to check permissions on a Spring Co

2019-08-04 02:55发布

问题:

The JS client of my REST API wants to know, is a query to a certain URL permitted or not. Permissions are configured on the controller methods using the standard annotations:

@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"
  }
}

For read-only methods it would be possible to program the JS client to try and access a URL itself, ignore the result and look only on the status (200 or 403-Forbidden). It's not best performance-wise, but at least correct functionally. But for the write method I see no way to work around. Hope there is a sane solution for this problem.

P.S. Thanks to @Bogdan for the solution. This is the full text of the method I need:

@Autowired
WebInvocationPrivilegeEvaluator evaluator;

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

回答1:

For the UtilController you posted you could go with something like a WebInvocationPrivilegeEvaluator, maybe also have a look at how the authorize tag works.

Additionally, depending on what you are doing, something like this could also work:

@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() { }
}

You can then check the status code for calling the new methods.