I have implemented token based authentication(without spring security). So in GenericFilterBean, it checks and claims token.
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);
    }
}
So in this filter it seems all okay. But I need to send response with different Http Statutes with a json. I am able to use ResponseEntitiyExceptionHandler with @ControllerAdvice. So I can handle exceptions in my controllers.
@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);
    }
}
I know how it works and which order Filter and controllers and their exceptions(filters do their job before controllers, so they're not same scope with controllers). So naturally I can't handle filter's exceptions with ControllerAdvice.
So what is the efficient way to handle exceptions in Filters(like my example way)? Can you suggest me another way about it?
Exception HandlerThe @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.
Spring security exceptions can be directly handled by adding custom filters and constructing the response body. To handle these exceptions at a global level via @ExceptionHandler and @ControllerAdvice, we need a custom implementation of AuthenticationEntryPoint.
AuthenticationEntryPoint is used to send an HTTP response that requests credentials from a client. Sometimes a client will proactively include credentials such as a username/password to request a resource.
You should use response.sendError for send error code and status :
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);
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With