2015-07-18 11 views
12

Ich habe tokenbasierte Authentifizierung implementiert (ohne Federsicherheit). Also in GenericFilterBean, es überprüft und Ansprüche Token.Ausnahmebehandlung im Frühling 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); 

    } 

} 

Also in diesem Filter scheint alles in Ordnung zu sein. Aber ich muss Antwort mit verschiedenen HTTP-Statuten mit einem JSON senden. Ich kann ResponseEntitiyExceptionHandler mit @ControllerAdvice verwenden. So kann ich Ausnahmen in meinen Controllern behandeln.

@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); 
    } 
} 

Ich weiß, wie es funktioniert und welcher Reihenfolge Filter und Controller und deren Ausnahmen (Filter machen ihre Arbeit vor Controller, so dass sie nicht denselben Umfang mit Controllern). Natürlich kann ich die Ausnahmen des Filters nicht mit ControllerAdvice umgehen.

Also, was ist der effiziente Weg, Ausnahmen in Filtern (wie mein Beispiel) zu behandeln? Kannst du mir einen anderen Weg vorschlagen?

Antwort

7

Sie response.sendError für Sendefehlercode und Status verwendet werden soll:

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); 
    } 
}