Question

I have a Solr server running as a webapp on jetty. I now want to add a custom authentication procedure to jetty, to ad/remove users that can access the solr search.

The user sends a token that needs to be verified by a 3. party server before the user is allowed to access the solr server.

How can i intercept requests to the solr server from within jetty and do some kind of session management for authenticated users?

Somebody posted a similar question for tomcat: implementing-custom-authentication-with-tomcat the answer there was to use filters. There are some filter classes available for jetty, but are they similar to tomcat and how would i deploy my own filter class?

Are there any tutorials for these kind of problems?

Was it helpful?

Solution

Well nobody seems to answer so i will start answering my own question step by step.

Filters are the right approach to my problem. They are not something that is tomcat or jetty specific, instead they are standardized by the Java Servlet specification version 2.3. So both tomcat or jetty or any other webserver that implements the Java Servlet specification should run filters.

As example for a use case for filters, this oracle/java article lists: "Authentication-Blocking requests based on user identity."

this is exactly what i want to do. I will try using filters and update this answer with my progress, until i find that the question is sufficiently answered.

Step 1, preparations for Filter development
before you can start writing your own filter you have to setup your IDE for JavaEE development or write the required build files for your build tool. There are a lot of tutorials out there already explaining this. for Example: Eclipse + Tomcat Maven + Jetty

Step 2, write the most simple hello world filter

package hello.world.filter;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloWorldFilter implements Filter {

    public void init(FilterConfig fConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        
        PrintWriter out = response.getWriter();
        out.print("hello World");
    }

    public void destroy() {
    }

}

Step 3, deploy your filter on your running solr server
Now this step is not as easy as you might think it is. I thought i could just package my authentication filter into a war file and then use it for just any application i have running on any servlet server. Sadly it doesn't seem to work like that. Every webapp gets deployed on your server in its own context an cannot access the context of other webapps (at least on jetty as far as i know). Solr itself for example is a webapp, and has the context http://localhost:8983/solr/. Even if you would deploy you webapp in the context http://localhost:8983/* or http://localhost:8983/solr/* this would not affect solr at all and everyone would still be able to access your solr server.

The solution is to integrate your filter into the solr webapp. To do that you have to first package your HelloWorldFilter.class into a jar file. Then go to the directory where your solr server is located and unpack the solr.war file. (In your standard installation this would normally be solr-4.1.0/example/webapps). Now you have to change the context file for the solr webapp, because its no longer packaged in solr.war but instead consists of a directory. Got to solr-4.1.0/example/contexts and open solr.xml. Change the line <Set name="war"><SystemProperty name="jetty.home"/>/webapps/solr.war</Set> into <Set name="war"><SystemProperty name="jetty.home"/>/webapps/solr</Set>. Now you can actually deploy your filter: Copy your jar file into the folder solr-4.1.0/example/webapps/solr/WEB-INF/lib. As a last step we have to let solr know that our filter should be deployed while solr starts. To do that open solr-4.1.0/example/webapps/solr/WEB-INF/web.xml and add the following lines:

   <filter>
    <filter-name>HelloWorldFilter</filter-name>
    <filter-class>hello.world.filter.HelloWorldFilter</filter-class>
  </filter> 

before the lines

<filter>
    <filter-name>SolrRequestFilter</filter-name>
    ...

And also ad:

<filter-mapping>
  <filter-name>HelloWorldFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

before any other filter mapping in the file.

Safe everything and restart your solr server. Instead of the solr web interface you should now see "hello world" on any context after http://localhost:8983/solr/.

Now you can start replacing

PrintWriter out = response.getWriter();
out.print("hello World");

with your own custom authentication inside the doFilter method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top