Search code examples
javaproxytwiliowebproxytwilio-api

twilio java connection with proxy authentication


I am setting up a java Twilio connection using the example Twilio java-sdk from the api examples here.

The only difference is I need to run my Twilio connection through a web-proxy with authentication.

There are other questions about connecting to Twilio through a web-proxy but no accepted answers. For example this, based on that answer I have tried implementing a solution like this:

import com.twilio.sdk.TwilioRestClient;
import com.twilio.sdk.TwilioRestException;
import com.twilio.sdk.resource.factory.MessageFactory;
import com.twilio.sdk.resource.instance.Message;

import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.message.BasicNameValuePair;

import java.util.ArrayList;
import java.util.List;

public class Example {

    // Find your Account Sid and Token at twilio.com/console
    public static final String  ACCOUNT_SID = "asdfasdfasdfdasf";
    public static final String  AUTH_TOKEN = "asdfasdfasdfasdf";
    public static final String  PROXY_ADDRESS = "1.2.3.4";
    public static final int     PROXY_PORT = 80;
    public static final String  PROXY_USER = "user";
    public static final String  PROXY_PASSWORD = "password";

    public static void main(String[] args) {

        //Set up Proxy host
        HttpHost proxy = new HttpHost(PROXY_ADDRESS, PROXY_PORT);
        DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);

        //Set up Proxy user credentials
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope(PROXY_ADDRESS, PROXY_PORT), 
                new UsernamePasswordCredentials(PROXY_USER, PROXY_PASSWORD));

        //Set up HttpClient with proxy and credentials
        CloseableHttpClient httpClient = HttpClients.custom()
                .setRoutePlanner(routePlanner)
                .setDefaultCredentialsProvider(credsProvider)
                .build();


        TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN); 
        client.setHttpClient(httpClient);


        // Build a filter for the MessageList
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Body", "Hello from Java"));
        params.add(new BasicNameValuePair("To", "+12345678901"));
        params.add(new BasicNameValuePair("From", "+12345678901"));

        MessageFactory messageFactory = client.getAccount().getMessageFactory();

        try {
            Message message;
            message = messageFactory.create(params);
            System.out.println(message.getSid());

        } catch (TwilioRestException e) {
            System.out.println(e.getErrorCode());
            System.out.println(e.getErrorMessage());
            e.printStackTrace();
        }

    }

}

It seems to be making it through the proxy with this and reaching the Twilio API but it returns a 20003 error every time. (permission denied)

I suspect that the http-client web proxy authentication is overwriting the twilio account SID and auth token but I am not sure, or if there is a way around this.

I have triple checked my own account SID and auth token and also tried using the "testing" SID and auth token that Twilio provides for the account also but I get the same result.

Any advice for running the Twilio java-sdk through a web proxy?

I am using apache http-client library 4.5.2


Solution

  • Resolved... just needed to add another set of credentials that were scoped to api.twilio.com after the proxy credentials:

        //Set up Proxy user credentials
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope(PROXY_ADDRESS, PROXY_PORT), 
                new UsernamePasswordCredentials(PROXY_USER, PROXY_PASSWORD));
    
        //Set up Twilio user credentials
        credsProvider.setCredentials(
                new AuthScope("api.twilio.com", 443), 
                new UsernamePasswordCredentials(ACCOUNT_SID, AUTH_TOKEN));
    

    I'll leave this here for posterity because there has been several questions about this but no accepted answers.