gpt4 book ai didi

java - 如何捕获 Spring Security 匹配器抛出的异常?

转载 作者:行者123 更新时间:2023-12-02 00:34:51 25 4
gpt4 key购买 nike

我有一个受 Spring Security 保护的后端,配置了 antMatchers() ,例如.antMatchers("/api/myProtectedUri/*").authenticated()

在同一个应用程序中,我使用 @ControllerAdvice@ExceptionHandler 来处理抛出的异常。为了保护 API 免于从后端返回不受控制的响应(例如堆栈跟踪),我编写了如下内容:

@ExceptionHandler({RuntimeException.class})
public ResponseEntity handleRuntimeException() {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Unexpected error occurred");
}

这导致测试失败,因为处理程序在保护端点时可能还会捕获 Spring Security 抛出的异常,状态代码为 500(来自处理程序),而不是预期的 401 或 403(来自 Spring)

我尝试使用自定义处理程序,例如:

.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())

它仍然被 @ExceptionHandler with RuntimeException 子句捕获。

我的问题是:

  1. Spring Security 抛出的异常是什么(如果我知道我可以单独处理它们)
  2. 单独捕获异常的想法对于问题是否正确,也许还有另一种解决方案,可以更好地完成我想做的事情?

最佳答案

Spring security基于filter,而Spring MVC基于servlet,@ExceptionHandler不应该捕获spring security抛出的异常。

.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())

这是一个ExceptionTranslationFilter,它将处理AuthenticationExceptionAccessDeniedException,源代码参见here

            Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(var10);
RuntimeException ase = (AuthenticationException)this.throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain);
if (ase == null) {
ase = (AccessDeniedException)this.throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain);
}

if (ase == null) {
if (var10 instanceof ServletException) {
throw (ServletException)var10;
}

if (var10 instanceof RuntimeException) {
throw (RuntimeException)var10;
}

throw new RuntimeException(var10);
}

if (response.isCommitted()) {
throw new ServletException("Unable to handle the Spring Security Exception because the response is already committed.", var10);
}

this.handleSpringSecurityException(request, response, chain, (RuntimeException)ase);

AuthenticationException(通常表示未通过身份验证)将由AuthenticationEntryPoint处理,您可以实现自己的AuthenticationEntryPoint,只需覆盖 start 方法,例如HttpStatusEntryPoint,它只返回带有客户状态的响应。

public final class HttpStatusEntryPoint implements AuthenticationEntryPoint {
private final HttpStatus httpStatus;

public HttpStatusEntryPoint(HttpStatus httpStatus) {
Assert.notNull(httpStatus, "httpStatus cannot be null");
this.httpStatus = httpStatus;
}

public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setStatus(this.httpStatus.value());
}
}

并且可以设置异常处理的入口点。

exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))

AccessDeniedHandler(通常表示未授权)将由您已完成的AccessDeniedHandler处理。

关于java - 如何捕获 Spring Security 匹配器抛出的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57988088/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com