Home > Software engineering >  Spring authentication filter throwing wrong error message
Spring authentication filter throwing wrong error message

Time:11-28

I have a custom filter that is used to authenticate the user. I am always getting full authentication requried error even though I have thrown a custom exception with specific message & added exception handler as well.

Code for filter:

@Slf4j
@Component
public classTokenValidationFilter extends OncePerRequestFilter {

  @Autowired
  private TokenValidationHelper tokenValidationHelper;

  @Override
  protected void doFilterInternal(HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse,
            FilterChain filterChain) throws ServletException, IOException {
    HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
    HttpServletResponse httpResponse = (HttpServletResponse)servletResponse;
    MultiReadRequestWrapper request = new MultiReadRequestWrapper(httpRequest);
    SecurityContext context = SecurityContextHolder.getContext();
    // check if already authenticated
    if (context.getAuthentication() == null) {
      Authentication authentication = 
        tokenValidationHelper.validateAndAuthenticate(request);
        context.setAuthentication(authentication);
    }
    filterChain.doFilter(request, httpResponse);
  }
}

Code for exception handler:

@ControllerAdvice
public class ExceptionHandler {


  @ExceptionHandler({IrrecoverableAuthException.class})
  @ResponseBody
  @ResponseStatus(HttpStatus.UNAUTHORIZED)
  public RegistrationErrorResponse handleInternalServerException(IrrecoverableAuthException exception) {
    return getErrorResponse(exception , Category.Error exception.getMessage());
  }
}

But still getting wrong message

"Full authentication access is required to access this resource"

CodePudding user response:

Exception handler won't be invoked from within the filter. You can use HttpServletResponse from within the filter and write your error response manually as follows:

  protected void onFailedAuthentication(
      HttpServletRequest request,
      HttpServletResponse response,
      IrrecoverableAuthException failed) {
    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
    response.setStatus(failed.getStatus().getStatusCode());

    try (OutputStream out = response.getOutputStream()) {
      out.write(MAPPER.writeValueAsBytes(getErrorResponse())); // build the required response here
      out.flush();
    } catch (IOException e) {
      response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
  }

Call this method from your filter

@Slf4j
@Component
public classTokenValidationFilter extends OncePerRequestFilter {

  @Autowired
  private TokenValidationHelper tokenValidationHelper;

  @Override
  protected void doFilterInternal(HttpServletRequest servletRequest, 
            HttpServletResponse servletResponse,
            FilterChain filterChain) throws ServletException, IOException {
    HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
    HttpServletResponse httpResponse = (HttpServletResponse)servletResponse;
    MultiReadRequestWrapper request = new MultiReadRequestWrapper(httpRequest);
    SecurityContext context = SecurityContextHolder.getContext();
    // check if already authenticated
    if (context.getAuthentication() == null) {
      try {
        Authentication authentication = 
        tokenValidationHelper.validateAndAuthenticate(request);
        context.setAuthentication(authentication);
      } catch(IrrecoverableAuthException ex) {
        onFailedAuthentication(httpRequest, httpResponse, ex);
      }
    }
    filterChain.doFilter(request, httpResponse);
  }
}
  • Related