Issue
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.
@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"
Solution
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);
}
}
Answered By - deepakchethan
Answer Checked By - Marie Seifert (JavaFixing Admin)