Pergunta

I've got a Java app that runs on Heroku that needs to access Salesforce, which only allows API access from IPs that you whitelist. Proximo is a Heroku add-on that allows you to proxy all of the requests your app makes through a single server with a static IP. Unfortunately, the standard way of doing this—running your app within Proximo's wrapper—mucks up the creating of a listening socket for my app's webserver, as it seems to for a number of folks.

How can I use Proximo as a SOCKS proxy in my Java application?

Foi útil?

Solução

I looked that stacklet that they distribute as the aforementioned wrapper and saw 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 (Groovy syntax):

URL proximo = new URL(System.getenv('PROXIMO_URL')
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', '1080')
Authenticator.setDefault(new ProxyAuth(user, password))

With that ProxyAuth being an inner class elsewhere:

private class ProxyAuth extends Authenticator {
    private PasswordAuthentication passwordAuthentication;

    private ProxyAuth(String user, String password) {
        passwordAuthentication = new PasswordAuthentication(user, password.toCharArray())
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return passwordAuthentication;
    }
}

Outras dicas

What kind of java based web application is described here? I have a Spring MVC based web application, encountering the same issues as mentioned here.

I tried 2 ways to configure SOCKS proxy in my app:

  1. Using command line JVM args.
  2. Using the java code mentioned here, wrapped in a Bean which I load in my root application context.

My Java class loaded as bean:

package be.example.backend.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;

public class ProximoSocksConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProximoSocksConfig.class);
    private static final String PROXIMO_ENV_VAR = "PROXIMO_URL";
    private static final String PROXIMO_PORT = "1080";

    public ProximoSocksConfig() throws MalformedURLException {
        setup();
    }

    /**
     * Setup Proximo proxying
     *
     * @return True if Proximo was configured, false if the Proximo environment variable was not found
     */
    public static boolean setup() throws MalformedURLException {

        String proximoUrl = System.getenv(PROXIMO_ENV_VAR);

        if (proximoUrl != null) {
            URL proximo = new URL(proximoUrl);

            String userInfo = proximo.getUserInfo();
            String user = userInfo.substring(0, userInfo.indexOf(':'));
            String password = userInfo.substring(userInfo.indexOf(':') + 1);
            String host = proximo.getHost();

            System.setProperty("socksProxyHost", host);
            System.setProperty("socksProxyPort", PROXIMO_PORT);

            Authenticator.setDefault(new ProxyAuth(user, password));
            LOGGER.info("{} specified; using <{}:{}> {}:{} as SOCKS proxy", PROXIMO_ENV_VAR, user, password, host,
                    PROXIMO_PORT);
            return true;
        }

        LOGGER.info("{} environment variable not set", PROXIMO_ENV_VAR);
        return false;
    }

    private static class ProxyAuth extends Authenticator {

        private final PasswordAuthentication passwordAuthentication;

        private ProxyAuth(String user, String password) {
            passwordAuthentication = new PasswordAuthentication(user, password.toCharArray());
        }

        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return passwordAuthentication;
        }
    }
}

My XML based root application context:

<!-- Proximo SOCKS proxy configuration -->
<bean id="proximoSocksConfig" class="be.example.backend.configuration.ProximoSocksConfig"/>

I did not get the binding error anymore, because the proximo binary wrapper is not used anymore, but my application is not reachable on the public IP address provided by Proximo (I use the Proximo Starters package).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top