I have my Spring Security bean which is doing well in blocking unauthorised requests, while using Tomcat, the error response is a clean exception with the message but with Jetty, a text/html is returned even in postman as shown below. enter image description here And my doFilterInternal JWT Filter is as below.

public class JwtFilter extends OncePerRequestFilter {

    @Autowired
    private JWTUtility jwtUtility;

    @Autowired
    private UserServiceImpl userService;
    private final ObjectMapper mapper;


    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String authorization = httpServletRequest.getHeader("Authorization");
        String token = null;
        String userName = null;

        if(null != authorization && authorization.startsWith("Bearer ")) {
            token = authorization.substring(7);
            userName = jwtUtility.getUsernameFromToken(token);
        }

        if(null != userName && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails
                    = userService.loadUserByUsername(userName);
            try {
                if (jwtUtility.validateToken(token, userDetails)) {
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                            = new UsernamePasswordAuthenticationToken(userDetails,
                            null, userDetails.getAuthorities());

                    usernamePasswordAuthenticationToken.setDetails(
                            new WebAuthenticationDetailsSource().buildDetails(httpServletRequest)
                    );

                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            } catch (Exception e){
//                System.out.println("Hello world");
                Map<String, Object> errorDetails = new HashMap<>();
                errorDetails.put("ACCESS_DENIED", e.getMessage());
                httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
                httpServletResponse.setContentType(String.valueOf(MediaType.APPLICATION_JSON));
                mapper.writeValue(httpServletResponse.getWriter(), errorDetails);
                return;
            }

        }

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

With Tomcat as my server, everything works as expected, but I have shifted to Jetty Server, how best can I replace this code below to work the same for Jetty?

Map<String, Object> errorDetails = new HashMap<>();
                errorDetails.put("ACCESS_DENIED", e.getMessage());
                httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
                httpServletResponse.setContentType(String.valueOf(MediaType.APPLICATION_JSON));
                mapper.writeValue(httpServletResponse.getWriter(), errorDetails);
                return;

My expected response when the user has not sent in their jwt is as follows:-

HTTP 401 Unauthorized
{
    "ACCESS_DENIED": "Some error message here",
}

Otherwise, the request should go through therefore the filter should not return anything.

Note: Please feel free to edit this question to make it better as I have more friends trying to solve the same issue.

1

There are 1 best solutions below

1
Joakim Erdfelt On

The response you are seeing is the default Servlet ERROR dispatch handling (see DispatcherType.ERROR)

Use the standard Servlet error-page mappings to specify your own custom mappings for handling errors. A mapping can be based on status codes, throwables, and more (see Servlet descriptor and <error-page> mappings)