Twitter oAuth error 32 Could not authenticate you using Java on App Engine


#1

Using Twitter API from Java in Google App Engine and I am trying to verify credentials to get the id_str and I am getting error 32 - Could not authenticate you https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials

I am trying to better understand how oAuth works, that is why I haven’t used a library. There are many similar questions to this on StackOverflow, but no answers.

I have worked through https://dev.twitter.com/docs/auth/implementing-sign-twitter and got the accessToken and secret OK.

If I overwrite the oauth_nonce and oauth_timestamp with the examples in the OAuth tool then my Signature base string and Authorization header match the example so I guess my signing part is OK.

I wonder if it is the way I’m issuing the GET from Java? Any help or pointers would be appreciated.

public String getTwitterID(String oauth_token, String oauth_token_secret){  
    String answer = "";         
    String oauth_signature_method = "HMAC-SHA1";
    String oauth_consumer_key = apiKey;
    String uuid_string = UUID.randomUUID().toString();
    uuid_string = uuid_string.replaceAll("-", "");
    String oauth_nonce = uuid_string; //random alphanumeric string
    //oauth_nonce = "e1c55102427763bf3570093497b445ff";
    String oauth_timestamp = (new Long(System.currentTimeMillis() / 1000))
            .toString(); 
    //The parameter string must be in alphabetical order
    //oauth_timestamp = "1397181466";
    String parameter_string = "oauth_consumer_key=" + oauth_consumer_key
            + "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method="
            + oauth_signature_method + "&oauth_timestamp="
            + oauth_timestamp
            + "&oauth_token=" + oauth_token
            + "&oauth_version=1.0";
    System.out.println("parameter_string=" + parameter_string);

    String signature_base_string = "";      
    try {
        signature_base_string = "GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Faccount%2Fverify_credentials.json&" + URLEncoder.encode(parameter_string, "UTF-8");
    } catch (UnsupportedEncodingException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    System.out.println("signature_base_string=" + signature_base_string);
    String oauth_signature = "";
    try {
        oauth_signature = computeSignature(signature_base_string,
                apiSecret + "&" + oauth_token_secret);
        System.out.println("oauth_signature=" + oauth_signature);
    } catch (GeneralSecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        oauth_signature = URLEncoder.encode(oauth_signature, "UTF-8");
        System.out.println("encoded oauth_signature=" + oauth_signature);
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    // The parameter list must be in alphabetical order
    String oauth_header = "OAuth oauth_consumer_key=\"";
    oauth_header += oauth_consumer_key;
    oauth_header += "\", oauth_nonce=\"";
    oauth_header += oauth_nonce;    
    oauth_header += "\", oauth_signature=\"";
    oauth_header += oauth_signature;
    oauth_header += "\", oauth_signature_method=\"";
    oauth_header += "HMAC-SHA1";
    oauth_header += "\", oauth_timestamp=\"";
    oauth_header += oauth_timestamp;
    oauth_header += "\", oauth_token=\"";
    oauth_header += oauth_token;
    oauth_header += "\", oauth_version=\"";
    oauth_header += "1.0\"";
    System.out.println("oauth_header=" + oauth_header);

    try {
        String request = "https://api.twitter.com/1.1/account/verify_credentials.json";
        //String request = "https://api.twitter.com/1.1/account/verify_credentials.json?" + parameter_string;
        URL url = new URL(request); 
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();           
        connection.setDoOutput(true);
        connection.setDoInput(true);
        //connection.setInstanceFollowRedirects(false); 
        connection.setRequestMethod("GET"); 
        //connection.setRequestMethod("POST");

        //connection.setRequestProperty("charset", "utf-8");
        connection.setRequestProperty("Accept", "*/*"); 
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
        connection.setRequestProperty("Authorization", oauth_header);
        connection.setRequestProperty("Content-Length", "0");
        //connection.setRequestProperty("Content-Length", "" + Integer.toString(oauth_body.getBytes().length));
        connection.setUseCaches (false);
        DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
        //wr.writeBytes(oauth_body);
        wr.flush();
        wr.close();
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));     
        String line;
        StringBuilder str = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
            str.append(line);
        }
        reader.close();         
        connection.disconnect();     
        LOG.log(Level.WARNING, "Twitter ID JSON - " + str.toString());
        try {
            JSONObject jsonObject;
            jsonObject = new JSONObject(answer);
            answer = jsonObject.getString("id_str");
        } catch (JSONException e) {
            e.printStackTrace();
            answer = "";
        }           
    } catch (MalformedURLException e) {
        // ...
    } catch (IOException e) {
        // ...
    }
    System.out.println(answer);
    return answer;
}

#2

Use oauth_token_secret instead of oauth_token to compute keyString for the verify_credentials request