It took me hours to figure out (I'm not even sure if I would call this a progress) to make Spring Social work behind our proxy.
The main problem is there's no easy way to setup the proxy. A direct call to HttpClient is entirely impossible via plain XML config. (Maybe even via Java-config?)
Basically the idea is to modify the RequestFactory that is passed to RestTemplate's constructor. So that it contains the proxy settings:
The workaround is two parts:Code:SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("my.company.org", 9999)); requestFactory.setProxy(proxy); RestTemplate restTemplate = new RestTemplate(requestFactory);
First, I had to reimplement FacebookOAuth2Template createRestTemplate() method:
Literally, I created a new class and copied the whole implementation of FacebookOAuth2Template and renamed the new class as ModifiedFacebookOAuth2Template.Code:@Override protected RestTemplate createRestTemplate() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("my.company.org", 9999)); requestFactory.setProxy(proxy); RestTemplate restTemplate = new RestTemplate(requestFactory); FormHttpMessageConverter messageConverter = new FormHttpMessageConverter() { public boolean canRead(Class<?> clazz, MediaType mediaType) { // always read as x-www-url-formencoded even though Facebook sets contentType to text/plain return true; } }; restTemplate.setMessageConverters(Collections.<HttpMessageConverter<?>>singletonList(messageConverter)); return restTemplate; }
This works on the authentication part to Facebook. I can see clearly in the userconnection table that the Facebook connection has been created. However, when I try to view my profile and post to my wall, I get a timeout error. Again, it's because the proxy is not setup though I already did!
It turns out I also have to modify the RequestFactory that's declared inside the FacebookTemplate. This is the second part.
FacebookTemplate calls the following factory class to initialize its RestTemplate:
So basically I had to modify ProtectedResourceClientFactory and re-implemented it like the following:Code:this.restTemplate = ProtectedResourceClientFactory.draft10(accessToken);
But then in order for this to work, I had to literally copy 20+ classes and modify their visibility to public so that my custom package is able to see them! For example, EventTemplate, CommentList, AlbumList, ReferenceList, VideoList, OAuth2Version, and so forth.Code:private static RestTemplate version(String accessToken, OAuth2Version version) { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("my.company.org", 9999)); requestFactory.setProxy(proxy); RestTemplate client = new RestTemplate(requestFactory); if (interceptorsSupported) { // favored client.setInterceptors(new ClientHttpRequestInterceptor[] { new OAuth2RequestInterceptor(accessToken, version) }); } else { // 3.0.x compatibility client.setRequestFactory(new Spring30OAuth2RequestFactory(client.getRequestFactory(), accessToken, version)); } return client; }
It's too lengthy and takes a lot of work. The visibility of these classes made the modification tedious.
My application works, but I believe there should be a simpler way to set this up. I tried adding Apache Commons HttpClient 4.1 in the classpath and see if I can modify it's parameters so that the proxy settings are assingned to. Unfortunately, the HttpClient is created runtime and not via configuration.
I assume it would also work if I copy and modify the classes that contain HttpClient but that would even require more classes to edit.
Or maybe there's an easy that I've missed?


Reply With Quote
Thanks for opening-up a JIRA as well. I appreciate it.
