我正在嘗試自定義拋出的例外,但它不在建議控制元件中。
TokenExpiredException 例外應該在控制器通知中處理,但回傳一個常見的、未處理的錯誤。
JWTValidarFilter:
public class JWTValidarFilter extends BasicAuthenticationFilter{
private static final String HEADER_ATRIBUTO = "Authorization";
private static final String ATRIBUTO_PREFIXO = "Bearer ";
public JWTValidarFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String atributo = request.getHeader(HEADER_ATRIBUTO);
if(atributo == null) {
chain.doFilter(request, response);
return;
}
if(!atributo.startsWith(ATRIBUTO_PREFIXO)) {
chain.doFilter(request, response);
return;
}
String token = atributo.replace(ATRIBUTO_PREFIXO, "");
UsernamePasswordAuthenticationToken authenticationToken = getAuthenticationToken(token);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
chain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthenticationToken(String token) {
try {
String usuario = JWT.require(Algorithm.HMAC512(JWTAutenticarFilter.TOKEN_SENHA))
.build()
.verify(token)
.getSubject();
if(usuario == null) {
return null;
}
return new UsernamePasswordAuthenticationToken(usuario, null, new ArrayList<>());
} catch (TokenExpiredException e) {
throw new TokenExpiredException("Token expirado!");
}
}
}
自定義ResponseEntityExceptionHandler:
@ControllerAdvice
@RestController
public class CustomizeResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{
@ExceptionHandler(Exception.class)
public final ResponseEntity<ExceptionResponse> handleAllExcepetions(Exception ex, WebRequest request){
ExceptionResponse exceptionResponse =
new ExceptionResponse(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(InvalidJwtAuthenticationException.class)
public final ResponseEntity<ExceptionResponse> invalidJwtAuthenticationException(Exception ex, WebRequest request){
ExceptionResponse exceptionResponse =
new ExceptionResponse(new Date(),
ex.getMessage(),
request.getDescription(false));
return new ResponseEntity<>(exceptionResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(TokenExpiredException.class)
public final ResponseEntity<ExceptionResponse> TokenExpiredException(TokenExpiredException ex, WebRequest request){
ExceptionResponse exceptionResponse =
new ExceptionResponse(new Date(),
ex.getMessage(),
request.getDescription(true));
return new ResponseEntity<>(exceptionResponse, HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(HttpClientErrorException.class)
public ResponseEntity<String> handleException(HttpClientErrorException ex) throws HttpClientErrorException {
System.out.println("*******Exception Occured: *************" ex);
return ResponseEntity
.status(HttpStatus.UNAUTHORIZED)
.body(" -----DD------ Exception: " ex.getLocalizedMessage());
}
}
2021-09-28 10:13:38.729 錯誤 25385 --- [nio-8080-exec-2] oaccC[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] 在背景關系中路徑 [] 拋出例外 com.auth0.jwt.exceptions.TokenExpiredException:令牌過期!
uj5u.com熱心網友回復:
嘗試AuthenticationFailureHandler按如下方式構建自定義:
public class CustomAuthenticationFailureHandler
implements AuthenticationFailureHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
Throwable cause = exception.getCause();
ExceptionResponse exceptionResponse = null;
if (cause instanceOf InvalidJwtAuthenticationException) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
exceptionResponse = new ExceptionResponse(new Date(),
cause.getMessage(),
request.getDescription(false));
} else if (cause instanceOf TokenExpiredException) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
exceptionResponse = new ExceptionResponse(new Date(),
ex.getMessage(),
request.getDescription(true));
} else {
// additional logic here
}
response.getOutputStream().println(objectMapper.writeValueAsString(exceptionResponse));
}
}
然后你需要在一個@Configuration類中注冊它:
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
uj5u.com熱心網友回復:
您無法使用控制器建議捕獲身份驗證例外(至少不是那么簡單:-)。身份驗證例外發生在整個 Spring 例外處理程式初始化之前。以下是如何解決相關問題的類似討論:
Spring MVC(或 Spring Boot)。針對安全相關例外的自定義 JSON 回應,例如 401 Unauthorized 或 403 Forbidden)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/324127.html
上一篇:嘗試使日期疼痛時,laravel中的Carbon\Exceptions\InvalidFormatException問題
