12

我们正在使用具有方法级安全性的 Spring Security 3.1.3-RELEASE。它完美地工作。

我想记录,也许向用户展示他为什么被拒绝访问。

使用org.springframework.security.web.access.AccessDeniedHandlerImpl子类,我可以获得对org.springframework.security.access.AccessDeniedException抛出的引用,但我无法找到一种方法来确定导致它的原因(例如,'缺少角色 ROLE_ADMIN' 或类似的东西)。

我错过了什么,还是根本不存在?

4

3 回答 3

5

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

我研究了源代码并...

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

  • 基于肯定的
  • 基于共识
  • 一致为基础

他们每个人都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

于 2012-11-06T19:05:10.220 回答
1

我还为此创建了一个 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"

于 2015-09-10T12:27:13.273 回答
1

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

于 2020-11-15T15:18:25.867 回答