今天在使用 Spring Security 进行注解鉴权的时候发现一个问题,权限不足的异常居然被 SpringBoot 的全局异常处理器捕获了,而不是 Spring Security 的过滤链中负责异常处理的过滤器捕获的,返回的JSON数据如下:
{
"code": 500, // 全局异常处理器器中指定的自定义响应码
"msg": "不允许访问" // 这里在全局异常处理器中是使用 e.getMessage(),所以是 权限不足异常自己生成的 msg 内容
}
为了排除问题,于是又使用配置类的方式配置了鉴权,这次的异常成功被 Spring Security 的过滤链 捕获了,返回的JSON数据如下:
{
"code": 403,
"msg": "无权限操作"
}
这就不奇怪了,因为这是我自己定义的 鉴权失败处理器 返回的结果。
总结:
1、Spring Security 配置类方式配置的鉴权,是会在 Spring Security 的过滤链 中进行鉴权的,而注解方式配置的鉴权,则会在过滤链之后,进入Controller之前(最起码已经在Spring Boot的全局异常处理器之后)之间进行的鉴权。
2、由 "msg":"不允许访问" 可知,Spring Security 可能还做了一点国际化,不然返回的msg应该是英文。
3、具体原因还需要深入 Spring Security 源码才可知,作者时间有限,之后有空可以研究一下,这里做一个记录。有了解的大佬也可以在评论区解答一下,感谢。
解决方案:
1、不采用注解鉴权,全部使用配置类进行配置。(我觉得太麻烦了哈哈哈)
2、直接在 Spring Boot 的全局异常处理器中对这个权限不足的异常进行处理
3、在 Spring Boot 的全局异常处理器中继续向上抛出权限不足的异常,让 Spring Security 过滤链里的 自定义的鉴权失败处理器 进行处理。
作者选择 3,因为我觉得要职责分明,权限不足异常还是应该由 自定义的鉴权失败处理器 进行处理,不应该在 Spring Boot 的全局异常处理器中耦合处理权限不足异常的代码。