We have a Java application that runs on Heroku and interacts with the Salesforce API. Salesforce enforces strict security on the usage of their API by limiting access to a set of IPs that are white-listed by an organization’s administrator1. This is a bit of a snag, since Heroku abstracts away the existence of servers, so the IP address from which requests emanate can and will change.
The Proximo add-on solves this problem by providing you with a proxy to send traffic through, with an IP address that won’t change. Their integration instructions suggest running your application in a wrapper that they provide in their stacklet. Unfortunately, running our application within the wrapper mucks up the creation of the listening socket for the webserver:
Exception in thread "main" java.net.BindException: Cannot assign requested address
As an alternative to running your application within their wrapper, Proximo offers some examples of using it as an HTTP proxy, though they don’t provide an example for doing this in Java and for all my trying, I couldn’t get this to work globally through my Java application.
We looked through the aforementioned wrapper that Proximo distributes and found that it connects to the Proximo server as a SOCKS proxy. That’s easy to do in Java, so I added this to the startup of my app:
URL proximo = new URL(proximoUrl) String userInfo = proximo.getUserInfo() String user = userInfo.substring(0, userInfo.indexOf(':')) String password = userInfo.substring(userInfo.indexOf(':') + 1) System.setProperty('socksProxyHost', proximo.getHost()) System.setProperty('socksProxyPort', PROXIMO_PORT) Authenticator.setDefault(new ProxyAuthenticator(user, password))
That ProxyAuth is defined as an inner class elsewhere:
private class ProxyAuthenticator extends Authenticator { private final PasswordAuthentication passwordAuthentication; private ProxyAuth(String user, String password) { passwordAuthentication = new PasswordAuthentication(user, password.toCharArray()) } @Override protected PasswordAuthentication getPasswordAuthentication() { return passwordAuthentication; } }
With this configured, all requests initiated by the Java application are sent via SOCKS through the Proximo proxy. We just white list the proxy’s IP address in our Salesforce settings and everything works.
We have encapsulated this Proximo SOCKS setup code into a module, proximo-socks, that you can use in your application. Simply add it as a dependency in your pom.xml
or build.gradle
and then initialize it in your app’s startup:
import com.palominolabs.heroku.Proximo … Proximo.setup()
See also
Note that this only applies to username/password based authentication. Using the preferred Oauth method requires no whitelisting. ↩