class IncomingFilter implements ContainerRequestFilter, ConfigurationChangedListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(IncomingFilter.class);

    /**
     * Endpoint paths that are exempted from this filter.
     * @see SearchController#search(HttpServletRequest, String, String, String, String, String, String,
     * java.util.List, int, int)
     * @see SuggesterController#getSuggestions(org.opengrok.web.api.v1.suggester.model.SuggesterQueryData)
     * @see SuggesterController#getConfig()
     */
    private static final Set<String> allowedPaths = new HashSet<>(Arrays.asList(
            SearchController.PATH, SuggesterController.PATH, SuggesterController.PATH + "/config",
            HistoryController.PATH, FileController.PATH, AnnotationController.PATH,
            SystemController.PATH + "/ping"));

    @Context
    private HttpServletRequest request;

    private final Set<String> localAddresses = new HashSet<>(Arrays.asList(
            "127.0.0.1", "0:0:0:0:0:0:0:1", "localhost"
    ));

    static final String BEARER = "Bearer ";  // Authorization header value prefix

    private Set<String> tokens;

    private Set<String> getTokens() {
        return tokens;
    }

    private void setTokens(Set<String> tokens) {
        this.tokens = tokens;
    }

    @PostConstruct
    public void init() {
        try {
            localAddresses.add(InetAddress.getLocalHost().getHostAddress());
            for (InetAddress inetAddress : InetAddress.getAllByName("localhost")) {
                localAddresses.add(inetAddress.getHostAddress());
            }
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "Could not get localhost addresses", e);
        }

        // Cache the tokens to avoid locking.
        setTokens(RuntimeEnvironment.getInstance().getAuthenticationTokens());

        RuntimeEnvironment.getInstance().registerListener(this);
    }

    @Override
    public void onConfigurationChanged() {
        LOGGER.log(Level.FINER, "refreshing token cache");
        setTokens(RuntimeEnvironment.getInstance().getAuthenticationTokens());
    }

    @Override
    public void filter(final ContainerRequestContext context) {<FILL_FUNCTION_BODY>}
}

        if (request == null) { // happens in tests
            return;
        }

        String path = context.getUriInfo().getPath();
        boolean isTokenValid = Optional.ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION))
                .filter(authHeaderValue -> authHeaderValue.startsWith(BEARER))
                .map(authHeaderValue -> authHeaderValue.substring(BEARER.length()))
                .filter(getTokens()::contains)
                .isPresent();
        if (isTokenValid) {
            var sanitizedPath = path.replaceAll("[\n\r]", "_");
            if (request.isSecure() || RuntimeEnvironment.getInstance().isAllowInsecureTokens()) {
                LOGGER.log(Level.FINEST, "allowing request to {0} based on authentication token", sanitizedPath);
                return;
            } else {
                LOGGER.log(Level.FINEST, "request to {0} has a valid token however is not secure", sanitizedPath);
            }
        }

        if (allowedPaths.contains(path)) {
            LOGGER.log(Level.FINEST, "allowing request to {0} based on allow listed path", path);
            return;
        }

        // In a reverse proxy environment the connection appears to be coming from localhost.
        // These request should really be using tokens.
        if (request.getHeader("X-Forwarded-For") != null || request.getHeader("Forwarded") != null) {
            LOGGER.log(Level.FINEST, "denying request to {0} due to existence of forwarded header in the request",
                    path);
            context.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
            return;
        }

        if (localAddresses.contains(request.getRemoteAddr())) {
            LOGGER.log(Level.FINEST, "allowing request to {0} based on localhost IP address", path);
            return;
        }

        context.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
    
<no_super_class>