Results 1 to 10 of 17

Thread: Proxy Workaround for M3

Hybrid View

  1. #1
    Join Date
    Dec 2010
    Posts
    315

    Default Proxy Workaround for M3

    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:
    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);
    The workaround is two parts:

    First, I had to reimplement FacebookOAuth2Template createRestTemplate() method:

    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;
    	}
    Literally, I created a new class and copied the whole implementation of FacebookOAuth2Template and renamed the new class as ModifiedFacebookOAuth2Template.

    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:

    Code:
    	this.restTemplate = ProtectedResourceClientFactory.draft10(accessToken);
    So basically I had to modify ProtectedResourceClientFactory and re-implemented it like the following:
    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;				
    	}
    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.

    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?

  2. #2
    Join Date
    Aug 2004
    Posts
    1,067

    Default

    You're right in saying that there is no easy way to configure Spring Social to be used behind a proxy. But this should definitely be addressed. Therefore, I've created https://jira.springsource.org/browse/SOCIAL-146 to track this issue and will be working to resolve it.
    Craig Walls
    Spring Social Project Lead

  3. #3
    Join Date
    Dec 2010
    Posts
    315

    Default

    Thanks for confirming it. At least this gives me comfort that I haven't missed a thing Thanks for opening-up a JIRA as well. I appreciate it.

  4. #4
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    We just landed a patch that allows the RequestFactory to be configured against each API binding. It's available now in the latest snapshot. Let us know if that meets your needs!
    Keith Donald
    Core Spring Development Team

  5. #5
    Join Date
    Aug 2004
    Posts
    1,067

    Default

    The latest snapshot builds include the ability to specify the proxy host/port using the "http.proxyHost" and "http.proxyPort" system properties (commonly set on the JVM via -Dhttp.proxyHost=somehost -Dhttp.proxyPort=8080). This works without the need to configure a custom request factory. Could you try this out and let us know if it works for you and meets your needs? Thanks!
    Craig Walls
    Spring Social Project Lead

  6. #6
    Join Date
    Dec 2010
    Posts
    315

    Default

    That's nice to know. I will certainly try it later. I will have to be at work to test it I've just woke-up (6am here).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •