2015-07-18 5 views
12

Ho implementato l'autenticazione basata su token (senza sicurezza di primavera). Quindi in GenericFilterBean, controlla e rivendica il token.Gestione delle eccezioni in Spring GenericFilterBean

public class MyTokenFilter extends GenericFilterBean { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws MyAuthException { 

     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

     if (!"OPTIONS".equals(request.getMethod())) { 

      String authHeader = request.getHeader("Authorization"); 

      if (authHeader == null || !authHeader.startsWith("Token ")) { 
       throw new MyAuthException("Authorization header needed"); // Should return custom http status response like 400 
      } 

      String token = authHeader.substring(6); 

      try { 
       claimToken(token); 
      } catch (Exception e) { 
       throw new MyAuthException("Invalid token."); // Should return custom http status response like 401 
      } 

     } 

     chain.doFilter(req, res); 

    } 

} 

Quindi in questo filtro sembra tutto ok. Ma ho bisogno di inviare una risposta con diversi statuti HTTP con un json. Sono in grado di utilizzare ResponseEntitiyExceptionHandler con @ControllerAdvice. Quindi posso gestire le eccezioni nei miei controller.

@ControllerAdvice 
public class MyPrettyExceptionHandler extends ResponseEntityExceptionHandler { 

    @ExceptionHandler(MyAuthException.class) 
    @ResponseBody 
    public ResponseEntity<Object> handleCustomException(HttpServletRequest req, MyAuthException ex) { 
     Map<String, String> responseBody = new HashMap<>(); 
     responseBody.put("error", "true"); 
     responseBody.put("message", ex.getMessage()); 
     return new ResponseEntity<Object>(responseBody, HttpStatus.INTERNAL_SERVER_ERROR); 
    } 
} 

so come funziona e quali ordinare filtro e regolatori e le loro eccezioni (filtri fanno il loro lavoro prima di controller, quindi non sono stessa portata con i regolatori). Quindi, naturalmente, non posso gestire le eccezioni dei filtri con ControllerAdvice.

Quindi qual è il modo efficace per gestire le eccezioni nei filtri (come nel mio esempio)? Puoi suggerirmi un altro modo?

risposta

7

Si dovrebbe usare response.sendError per il codice di errore di invio e di stato:

public class MyTokenFilter extends GenericFilterBean { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

     if (!"OPTIONS".equals(request.getMethod())) { 

      String authHeader = request.getHeader("Authorization"); 
      if (authHeader == null || !authHeader.startsWith("Token ")) { 
       //throw new MyAuthException("Authorization header needed"); // Should return custom http status response like 400 
       response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Authorization header needed"); 
       return ; 
      } 

      String token = authHeader.substring(6); 
      try { 
       claimToken(token); 
      } catch (Exception e) { 
       //throw new MyAuthException("Invalid token."); // Should return custom http status response like 401 
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token."); 
       return ; 
      } 
     } 
     chain.doFilter(req, res); 
    } 
}