SOLR server with basic authentication in Spring
Posted: October 5th, 2010 | Author: bart | Filed under: Java, Spring, Web Development | Tags: authentication, basic, httpclient, solr, spring | No Comments »About SOLR
SOLR is a great search server, written under the Apache license.
This means 2 things: it’s free and supported by a great community of experts!
It’s important to know that SOLR consists of 2 parts:
- The solr server: a standalone Java application that handles data management and searching
- The solr web applicaton: provides web services and handles requests. Deploy this to Tomcat, or use the integrated Jetty
Also, solr provides a Java interface called SOLRj.
SOLRj provides 2 ways of connecting to your SOLR server:
- EmbeddedSolrServer connects directly to your SOLR server core and omits the web application
- CommonsHttpSolrServer connects to the SOLR web app
Now I hear you thinking: why would I go via the Web App when I can connect directly to the core?
The answer is simple: distributed servers. Imagine your web application is divided among multiple servers in order to balance the load, you can’t connect to the SOLRCore, unless you use multiple solr instances (which I don’t at the moment).
The Problem
So we’re using the SOLR web app on 1 server, and we use it’s webservices.
However, we don’t really want to leave it nice and open so any scriptkiddie can just connect to http://yourprettysolrserver.com/solr/admin/. So we use Basic HTTP authentication (I know, still not very secure. But the communication will only happen between the 2 virtual servers, so no chance of a Man in the Middle attack).
On notes how to secure your SOLR via basic auth, visit the SolrSecurity Wiki page.
The Solution
SolrJ uses Apache’s
So doing it in Java should go in a jiffy(as described here).
My solution was a bit quick, and maybe a bit dirty, but it works!
I made a subclass of HttpClient:
public class BasicAuthHttpClient extends HttpClient { public BasicAuthHttpClient() { super(); } public BasicAuthHttpClient(String username, String pass) { super(); Credentials creds = new UsernamePasswordCredentials(username,pass); this.getState().setCredentials(AuthScope.ANY, creds); this.getParams().setAuthenticationPreemptive(true); } }
There’s a constructor that simply takes a username and password as argument.
In my ApplicationContext, I defined the following:
<bean id="solrHttpClient" class="com.example.system.utility.BasicAuthHttpClient"> <constructor-arg value="${solrserver_user}" /> <constructor-arg value="${solrserver_pass}" /> </bean> <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.CommonsHttpSolrServer"> <constructor-arg value="${solrserver_path}" /> <constructor-arg ref="solrHttpClient" /> </bean>
Works like a charm here! And should be thread safe.
Hope it helps somebody
