【问题标题】:How to catch custom annotations in Spring @ExceptionHandler?如何在 Spring @ExceptionHandler 中捕获自定义注释?
【发布时间】:2018-03-31 02:23:03
【问题描述】:

我有一个这样的自定义注释:

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@PreAuthorize(AllowedForSystemUsers.condition)
public @interface AllowedForSystemUsers {
    String condition = "hasAnyRole({'ROLE_ADMIN', 'ROLE_USER'})";
}

我将注释放在我的Controller 方法中,如下所示:

@RequestMapping(value="/search", method=RequestMethod.POST)
@AllowedForSystemUsers
public String searchRooms(@ModelAttribute Booking booking, Model model, long type) {

    //do something
}

我的ExceptionHandler 是这样的:

@ExceptionHandler(value = AccessDeniedException.class)
public ModelAndView accessDenied(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) {

    return new ModelAndView("redirect:/error");
}

所以当用户没有ROLE_ADMINROLE_USER 的身份验证时,会发生AccessDeniedException 并且代码会运行到accessDenied() 方法中。

我的问题是我怎么知道@AllowedForSystemUsers 注释是否触发了这个AccessDeniedException?因为其他代码也可能触发AccessDeniedException

谢谢!

【问题讨论】:

  • 你需要在控制器中抛出你的异常。要执行全局异常处理程序,您需要从其他地方抛出异常。
  • 你可以考虑创建AccessDeniedException的子类并在@AllowedForSystemUsers处理时抛出它
  • @SungJinSteveYoo 例如?
  • @AtaurRahmanMunna 所以你的意思是我不能使用 Spring Security 默认 AccessDeniedException?
  • 为什么不用内置的@PreAuthorize,见docs.spring.io/spring-security/site/docs/current/reference/html/…

标签: java spring spring-boot spring-security


【解决方案1】:

系统不应该给用户任何提示,为什么他没有被授权。他根本没有被授权。这是一个安全问题。此外,非管理员用户根本不能在前端调用任何管理员操作。这是可用性问题。

您想要以下内容(下次在您的问题中包含上下文信息):

我希望用户看到预订按钮并能够搜索可用房间 即使他没有登录,但当他想预订房间时,他会得到按摩 喜欢请登录第一条消息

这绝对没有问题。如果当前未登录的用户正在按下Book 按钮,我必须假设服务器将响应401 HTTP code。在您的前端,您只需对这个响应状态代码做出反应,向用户显示信息,他显然没有登录或您想做的任何事情。绝对没有必要,服务器需要告诉你他为什么回复401

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 2015-06-22
    相关资源
    最近更新 更多