class AuthenticationTokenProcessingFilter extends GenericFilterBean {

    private final UserDetailsService userDetailsService;

    @Autowired
    public AuthenticationTokenProcessingFilter(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = getAsHttpRequest(request);

        String authToken = extractAuthTokenFromRequest(httpServletRequest);
        String username = TokenUtils.getUserNameFromToken(authToken);

        if (username != null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (TokenUtils.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }

        chain.doFilter(request, response);
    }

    private HttpServletRequest getAsHttpRequest(ServletRequest request) {
        if (!(request instanceof HttpServletRequest)) {
            throw new RuntimeException("Expecting an HTTP request");
        }

        return (HttpServletRequest) request;
    }

    private String extractAuthTokenFromRequest(HttpServletRequest httpServletRequest) {<FILL_FUNCTION_BODY>}
}

        String authToken = httpServletRequest.getHeader("X-Auth-Token");
        if (authToken == null) {
            authToken = httpServletRequest.getParameter("token");
        }
        return authToken;
    
<no_super_class>