如何在Spring Security中获取AccessDeniedException的“原因”/原因?

时间:2012-11-06 18:08:37

标签: spring exception exception-handling spring-security

我们将Spring Security 3.1.3-RELEASE与方法级安全性一起使用。它运作得很好。

我想记录,并可能向用户显示为什么他被拒绝访问。

使用org.springframework.security.web.access.AccessDeniedHandlerImpl子类,我可以获得对引发的org.springframework.security.access.AccessDeniedException的引用,但我找不到确定导致它的原因的方法(例如,'缺少角色ROLE_ADMIN'或者其他内容那个效果)。

我错过了什么,或者它根本不存在?

3 个答案:

答案 0 :(得分:4)

不幸的是,Spring Security中没有可用的默认实现。

我调查了源代码并且......

MethodSecurityInterceptor负责保护方法调用。它将访问决策委托给AccessDecisionManager。 我检查了开箱即用的AccessDecisionManager的每个实现。

  • AffirmativeBased
  • ConsensusBased
  • UnanimousBased

他们每个人都以类似的方式抛出AccessDeniedException例外。

case AccessDecisionVoter.ACCESS_DENIED:
                throw new AccessDeniedException(
                      messages.getMessage("AbstractAccessDecisionManager.accessDenied",
                      "Access is denied")
                 );

AbstractAccessDecisionManager.accessDenied是邮件的名称,可以进行本地化。

英语是:

AbstractAccessDecisionManager.accessDenied=Access is denied

开箱即可使用多种语言,您可以自己翻译,但是......

这就是全部,没有关于例外原因的更多信息。

有关异常消息本地化的更多信息:

http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#localization

答案 1 :(得分:0)

我还为此创建了一个jira问题:https://jira.spring.io/browse/SEC-3104

@PreAuthorize, @PostAuthorize, @Secured注释可以有一个参数来指向自定义消息属性,以便设置详细的&更加用户友好的异常消息。

这也可以通过提供一个参数来完成。定义一个扩展AccessDeniedException的类名,以便让用户处理其余的事情。

这样,在处理复杂的规则时,如

@PreAuthorize("record.createuser != authentication.getName()")

我们可以得到像

这样的定义错误

"You cannot process a record that you created.""等而不是"Access is denied"

答案 2 :(得分:0)

我已经实现了一个解决方案,该解决方案(仅)适用于API层中使用的授权注释(例如,使用@RequestMapping)。在这里查看我的答案:https://stackoverflow.com/a/64846057/4413638