在使用GlobalExceptionHandler 进行全局捕获异常时,自定义了CustomAuthenticationEntryPoint去捕获springSecurity的异常,在GlobalExceptionHandler 也进行了捕获,但是CustomAuthenticationEntryPoint是捕获到了,但是GlobalExceptionHandler 无法捕获,这个怎么处理,具体代码如下
CustomAuthenticationEntryPoint类
package com.xjc.common.handler;
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
System.out.println(authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "认证失败,请重新登录");
}
}
GlobalExceptionHandler 类如下
package com.xjc.common.handler;
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Response handleGeneralException(Exception ex, WebRequest request) {
// 在这里可以记录异常信息到日志中
log.error("发生异常: " +ex.getMessage() , ex);
// 返回带有错误信息的响应
return ResponseCode.customizeResponse( true,HttpStatus.INTERNAL_SERVER_ERROR.value(),ex.getMessage());
}
@ExceptionHandler(value = AccessDeniedException.class)
public Response handleAccessDeniedException(AccessDeniedException ex, WebRequest request) {
// 处理AccessDeniedException的逻辑
log.error(ex.getMessage());
// ...
return ResponseCode.invalidHeaderTokenResponse(ex.getMessage());
}
@ExceptionHandler(value = AuthenticationException.class)
public Response handleAuthenticationException(AuthenticationException ex, WebRequest request) {
// 处理AuthenticationException的逻辑
log.error(ex.getMessage());
return ResponseCode.invalidHeaderTokenResponse(ex.getMessage());
}
}
Exception 和AuthenticationException都无法进行捕获,在jswt过滤器中是下面这么写的
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
LoginUserVO loginUserVO = (LoginUserVO) loginService.loadUserByUsername(username);
boolean isTokenValid = false;
//校验token准确性和是否过期,此处可以自定义校验,可以使用jwt自带的校验也可以通过数据库和redis等共同判断
// String userInfo= (String) stringRedisTemplate.opsForValue().get(StrUtil.format(OauthTestApplication.REDIS_TOKEN_KEY,jwt));
// if(StrUtil.isNotBlank(userInfo))isTokenValid=true;
User cacheObject = redisUntil.getCacheObject("login:" + username);
if(!Objects.isNull(cacheObject)) {
isTokenValid=true;
}
if(!isTokenValid){
throw new IOException("请重新登录");
}
if (loginUserVO != null && jwtService.isTokenValid(authHeader, loginUserVO) && isTokenValid) {
/**
* 封装成用户的凭证,传入用户实体类和用户的权限集合,spring security会自动去判断是否拥有权限
*/
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
loginUserVO,
null,
loginUserVO.getAuthorities()
);
/**
* 在 Spring Security 中,当用户进行认证时,会先通过 AuthenticationFilter 进行请求过滤,
* 然后调用 AuthenticationManager 进行认证。在认证过程中,Spring Security 会自动创建一个
* Authentication 对象,其中包含了认证请求的相关信息。如果你需要自定义 Authentication
* 对象的详细信息,就可以使用 WebAuthenticationDetailsSource 来创建 WebAuthenticationDetails 对象。
*/
authToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(req)
);
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
throw new IOException("请重新登录");报错后CustomAuthenticationEntryPoint是没有问题的,但是GlobalExceptionHandler 无法进行捕获,这个如何解决