与此问题类似,但没有答案:Spring Security: Handle InvalidBearerTokenException in @ExceptionHandler
我有类似的代码,当用户提供无效/过期/错误的
org.springframework.security.oauth2.server.resource.InvalidBearerTokenException
格式时,我试图捕获 JWT
。
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException e) throws IOException, ServletException {
resolver.resolveException(request, response, null, e);
}
}
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private CustomAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception
{
// other config here
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer().jwt();
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
}
}
我还实现了
@ExceptionHandler
的 AuthenticationException
用于自定义响应。
@ExceptionHandler({AuthenticationException.class})
protected ResponseEntity<Object> handleAuthException(AuthenticationException ex, WebRequest req)
{
CustomResponse response = ...
return new ResponseEntity<>(response, ...);
}
InvalidBearerTokenException
是 AuthenticationException
的子类。
知道为什么这个 AuthenticationEntryPoint
代码没有捕获它吗?我还尝试在 commence
方法中添加日志记录,但当抛出 InvalidBearerTokenException
时它不会被调用,但其他 AuthenticationException
会被调用。
您必须在
AuthenticationEntryPoint
中指定此 OAuth2ResourceServerConfigurer
,如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception
{
// other config here
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer().jwt().and()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
}
设置后,配置器将更改
AuthenticationEntryPoint
内部使用的 BearerTokenAuthenticationFilter
,请参阅此处。
现在语法已经发生了一些变化:
.oauth2ResourceServer(oauth2 -> oauth2.jwt(withDefaults())
.authenticationEntryPoint(new CustomAuthenticationEntryPoint()))
此外,
AuthenticationEntryPoint
可以是最终的:
public final class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException
) throws IOException, ServletException {
HttpStatus status = HttpStatus.UNAUTHORIZED;
response.setStatus(status.value());
}
}