ServletFilter extension point not called each time

Hello!

Due to some limitations of Sonarqube, and inability to get hold of the source code for the EE version to apply a patch (working patch on CE version); I’m a little forced to write a plugin.

I am starting very small with a ServletFilter and just logging the current request URL from the servlet filter.
I tried with and without doGetPattern overloaded and it makes no change: the logging occurs randomly.

The content of the class can be found below. And we’re using the latest current LTS version of Sonarqube : 8.9.9.

Is this a know bug in Sonarqube? What is curious to me is that with TRACE level enabled, I can see the class UserSessionFilter sonarqube/UserSessionFilter.java at 5fb0f5edafa247fafe76f50f24226528d6774638 · SonarSource/sonarqube · GitHub which does log the current request fine for all incoming requests

.
.
.
import org.sonar.api.web.ServletFilter;

public class UserHeader extends ServletFilter {
	private static final Logger LOG = Loggers.get(UserHeader.class);
	
//	private static final String ACCESS_LOG_LOGIN = "LOGIN";
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		LOG.info("Loaded " + getClass().getName());
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		LOG.info("{} serves {}", Thread.currentThread(), ((HttpServletRequest) request).getRequestURI());
/*		
		String userId = (String) ((HttpServletRequest) request).getAttribute(ACCESS_LOG_LOGIN);
		((HttpServletResponse) response).setHeader(ACCESS_LOG_LOGIN, userId);
*/
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
	}

}

Hello @Issa_G,

I would need a bit more information to help you:

  • Where (in the filter chain) do you register your filter? can you share the web.xml?
  • Are you always issuing the same request to SonarQube when you experience the random behaviour? can you give us a curl command with url/params/header that you are sending to SonarQube?

Due to some limitations of Sonarqube, and inability to get hold of the source code for the EE version to apply a patch (working patch on CE version)

Also, can you explain a bit more about your use case, to make sure I correctly understand your use case?

Thanks,
Aurélien

1 Like

Hello Aurélien,

Thank you for trying to help. The Servlet Filter is set inside a plugin as a ExtensionPoint.

The goal of this ServletFilter is to set the userid of the authenticated user into the response as a header so that a upfront reverse proxy can log information.

So, by just browsing in SOnarqube with a browser, I would like that the responses sent by Sonarqube include the userid inside their headers. So it does not matter what I’m sending as requests.

I hope it’s clearer. And I know it’s doable via the access logs of Sonarqube. It’s just that we use a corporate log analyzer on the reverse proxy and it would be nice to link requests with userid.

Hope it’s clearer…

THx

Hi,

I’m curious about your use case. You have a corporate need to track each request back to a user? And just enforcing permissions in SonarQube isn’t sufficient?

 
Thx,
Ann

Hey Ann, just being able to log the userid along with the requests inside a upfront reverse proxy. This can ease troubleshooting quite a lot. Thx

1 Like

Hi,

Thanks for this!

I hope you don’t mind my continuing to probe while not actually answering your question (sorry, but I’m not the one :smiley:). Is this about audit trailing? I’m asking because we added logging for security-sensitive operations in Enterprise Edition($$) in the 9-series, and I’m wondering if you’re trying to scratch that itch or a different one.

 
Ann

Thx Ann, but yeah , the audit is another stuff, different from what I’m trying to get. Thx

1 Like

Hello Issa

I tried myself and could observe the following behaviour:

  • when a server call is intercepted by a “final” filter like WebServiceFilter. Plugins filters are not invoked as the filters defined in the plugins are the last one in the filter chain.
  • the only time your custom filter is triggered, is when no filters are serving the resources requested; this happens mainly when a user hits F5 as this will reload a lot of resources and performs many server calls

From my observations the behaviour is not random, but it might look like it is, as depending on the actions performed by your users, your custom filter will be invoked or not (and it most cases it won’t).

This extension point was not designed with the idea to be able to intercept any requests, but rather to serve requests unserved by SonarQube.

Aurélien

Thx Aurélien to put some time into this. But keep in mind that Filters are not for serving requests, they are meant to do extra tasks for all or a group of request handler; they don’t take care of generating the request’s response. You can learn more on servlet filter with this excellent overview Servlet Filters and Event Listeners

There is a ExtensionPoint to handle requests themselves, which is sonar-plugin-api/RequestHandler.java at 1e3d8ff83d3d115233af900d4a80a64c5dcdfdaa · SonarSource/sonar-plugin-api · GitHub

So yes, you are right when saying it is not random, it is just that the choice made by Sonatqube is not documented and I don’t understand when the Filter is applied or not…

Regards

Hello Issa,

Thanks for your feedback, we might improve the documentation to make it clearer that adding a ServletFilter is not enough to gain access to every requests.

Aurélien