spring-boot - 如何自定义@PreAuthorize("isAuthenticated()") 返回的http状态?
问题描述
在我@PreAuthorize("isAuthenticated()")
用来检查用户是否登录的 Spring Boot 控制器中(使用基本身份验证 + JSESSIONID
)。
但是如果用户没有登录,即他们没有通过身份验证,控制器会返回403 Forbidden
.
根据我对身份验证与授权的了解, 401
用于身份验证,而403
用于授权。
根据我的理解@PreAuthorize()
,总是检查用户的授权(顾名思义),但是有没有办法根据我们传递给它的参数来定制它,即isAuthenticated()
这里?
我知道还有另一种解决方案:在 中使用基于 URL 的安全配置configure(HttpSecurity httpSecurity)
,但如果我不想这样做怎么办。
请有任何想法。
解决方案
当您使用比 spring 注释方法A@Pre/PostAuthorize
时,将为此类对象创建代理,并且对此类方法的每次调用都将通过代理(如果对象在 spring 上下文中)。
的代理@Pre/PostAuthorize
将评估来自注释的表达式(这里很复杂),如果它是真的,则传递请求父亲(到真正的方法),如果不是抛出 AccessDaniedException。你也可以在你的方法A中自己抛出这样的异常,效果是一样的。这一切都是关于如何@Pre/PostAuthorize
在这里不再有魔法!
但这不是故事的结局!
如果AccessDaniedException
没有被抑制或重新翻译(没有没有堆栈的堆栈AccessDaniedException
),它将ExceptionTranslationFilter
在 Spring Security 中被捕获并ExceptionTranslationFilter
查看用户是否已通过身份验证
如果是,
ExceptionTranslationFilter
则委托AccessDeniedHandler
处理这种情况,默认实现AccessDeniedHandler
将返回403 http 代码或重定向到错误页面,这取决于您是否使用休息。如果没有,
ExceptionTranslationFilter
则委托给AuthenticationEntryPoint
它,它将处理这种情况(重定向到登录页面,要求 http 基本 ... 等)。
注意:如果显示500ExceptionTranslationFilter
以外的任何异常,将重新AuthenticationException
抛出AccessDeniedException
异常:(
您的问题可能是另一个问题,请查看Spring Security 匿名 401 而不是 403
抑制:(:
@GetMapping(value = "/test/ok")
public String getOk() {
try {
myService.securedMethod();
return "ok";
} catch (Exception e) {
log.info("AccessDeniedException suppressed not rethrowing :(", e);
return "error";
}
}
正确重新翻译:):
@GetMapping(value = "/test/ok")
public String getOk() {
try {
myService.securedMethod();
return "ok";
} catch (AccessDeniedException e) {
throw new MyException(e); //public MyException(Throwable cause)
}
}
推荐阅读
- r - 用以下列中的数据填充空白值
- javascript - SAPUI5 表项重复 ID
- spring - DAO,SERVICE层是干什么用的
- typescript - “没有为突变配置架构。”
- javascript - 为什么我在解码 JSON Web 令牌时出现此错误错误:错误:0909006C:PEM 例程:get_name:没有起始行
- python - 有谁能够帮我。我被困在 Django 无法显示请求页面的这一步
- oracle-sqldeveloper - 将表数据导出到 SQL Developer 中没有的 csv 文件选项(版本 3.1.07)
- python - 如何在 python 中执行非阻塞脚本并获取其返回码?
- c# - MS Word 通过 COM-object 接口将图像添加到基板/水印
- reactjs - 反应路由器:动态 url id