1

I have got a google token and with it, I request an authentication URL from google with the following cURL command:

curl --data 'accountType=&Email=&has_permission=1&Token= + $$TOKEN$$ + &service=weblogin%3Acontinue%3Dhttps%253A//www.google.com/dashboard/&source=&androidId=&app=&client_sig=&device_country=&operatorCountry=&lang=&RefreshServices=' -k 'https://android.clients.google.com/auth'

How can I convert this command into a pure java command with URL connections or the Apache HTTP library? So that I don't have to use the cURL binary any more.

I saw several examples but I'm facing some troubles with the POST parameters. I can't get is right.

My java try:

$$ TOKEN $$ --> must be replaced by the real token.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class Test implements Runnable {

    public static void main(String args[]) {
        new Test();
    }

    public Test() {
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("https://android.clients.google.com/auth");

        try {

          List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
          nameValuePairs.add(new BasicNameValuePair("accountType", ""));
          nameValuePairs.add(new BasicNameValuePair("Email", ""));
          nameValuePairs.add(new BasicNameValuePair("has_permission", "1"));
          nameValuePairs.add(new BasicNameValuePair("Token", "$$ TOKEN $$"));
          nameValuePairs.add(new BasicNameValuePair("service", "weblogin%3Acontinue%3Dhttps%253A//www.google.com/dashboard/"));
          nameValuePairs.add(new BasicNameValuePair("androidId", ""));
          nameValuePairs.add(new BasicNameValuePair("app", ""));
          nameValuePairs.add(new BasicNameValuePair("client_sig", ""));
          nameValuePairs.add(new BasicNameValuePair("device_country", ""));
          nameValuePairs.add(new BasicNameValuePair("operatorCountry", ""));
          nameValuePairs.add(new BasicNameValuePair("lang", ""));
          nameValuePairs.add(new BasicNameValuePair("RefreshServices", ""));

          post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
          HttpResponse response = client.execute(post);
          BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

          String line = "";
          while ((line = rd.readLine()) != null) {
            System.out.println(line);

          }
        } catch (IOException e) {
          e.printStackTrace();
        }
    }
}

My eclipse console prints:

Url=https://www.google.com/accounts/ErrorMsg?id=unknown
Error=Unknown

SOLUTION:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class Test implements Runnable {

    public static void main(String args[]) {
        new Test();
    }

    public Test() {
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        String data;
        String selectedToken = "xxx YOUR TOKEN HERE xxx";

        try {
            data = "accountType=&Email=&has_permission=1&Token=" + selectedToken +
                    "&service=weblogin%3Acontinue%3Dhttps%253A//www.google.com/dashboard/&source=&androidId=" +
                    "&app=&client_sig=&device_country=&operatorCountry=&lang=&RefreshServices=";

            // Disable cert validation
            disableCertificateValidation();

            HttpURLConnection con = (HttpURLConnection) new URL("https://android.clients.google.com/auth").openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.getOutputStream().write(data.getBytes("UTF-8"));

            // Get the inputstream
            BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

            // .. and print it
            String tmp;
            while((tmp = reader.readLine()) != null) {
                System.out.println(tmp);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void disableCertificateValidation() {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() { 
                return new X509Certificate[0]; 
            }

            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }
        }};

        // Ignore differences between given hostname and certificate hostname
        HostnameVerifier hv = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
        } catch (Exception e) {
            // Do nothing
        }
    }
}

I just had to add the SSL cert validation and then it worked.

3
  • 1
    post your code and the error please Commented Aug 12, 2013 at 10:41
  • 1
    Is there a reason you're not using an OAuth library to handle all this? Commented Aug 12, 2013 at 10:42
  • I edited it into the first post. Commented Aug 12, 2013 at 13:47

1 Answer 1

1

If you use java.net.HttpURLConnection you can write the bytes of the post data right to the outputstream. So all you would have to do is take your --data and convert it to bytes and write it to the stream.

Sign up to request clarification or add additional context in comments.

2 Comments

I get a "javax.net.ssl.SSLHandshakeException" and a "java.security.cert.CertificateException". How can I bypass the SSL cert check - like the "-k" option of cURL does?
Your answer would work like a charme if the target URL is http. If the site has SSL, you need to add a ssl cert validation (see code in my first post) - then it works perfectly. Thanks ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.