7

i was using AsyncHttpClient link for making http calls but now our server has migrated to HTTPS and I am getting exception javax.net.ssl.SSLPeerUnverifiedException: No peer certificate . Has anyone tried making https call using this library ?

initialization of AsyncHttpClient :-

AsyncHttpClient client = new AsyncHttpClient();
            PersistentCookieStore myCookieStore = new PersistentCookieStore(
                    getActivity());
            // List<Cookie> cookies = myCookieStore.getCookies();
            myCookieStore.clear();
            // cookies = myCookieStore.getCookies();
            client.setCookieStore(myCookieStore);

            client.get(loginUrl, new JsonHttpResponseHandler() {

                @Override
                public void onStart() {
                    super.onStart();
                    progressBar.setVisibility(View.VISIBLE);
                }

                @Override
                public void onFinish() {
                    super.onFinish();
                    progressBar.setVisibility(View.GONE);
                }

                @Override
                public void onSuccess(int statusCode, JSONObject userInfo) {
                    super.onSuccess(statusCode, userInfo);

                    String errorMsg = null;
                    try {
                        errorMsg = userInfo.getString("error");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    if (errorMsg != null) {
                        errorMsg = getActivity().getResources().getString(
                                R.string.loginFailure)
                                + "\nError: " + errorMsg;
                        tvLoginFailure.setText(errorMsg);
                        tvLoginFailure.setVisibility(View.VISIBLE);

                    } else {
                        Subscriber.setEmail(email);
                        Subscriber.setPassword(password);
                        LoginUtility.saveUserInfo(getActivity(), userInfo);

                        if (Subscriber.getStatus().contentEquals("ACTIVE")) {
                            Intent intent;
                            if (MyApplication.ottMode) {
                                intent = new Intent(getActivity(),
                                        OTTMainScreen.class);

                            } else {
                                intent = new Intent(getActivity(),
                                        MainActivity.class);
                                intent.putExtra("SIGNEDIN", true);
                            }
                            if (MyApplication.ottMode) {
                                Utility.playSound(getActivity());
                            }
                            startActivity(intent);
                            getActivity().finish();

                        } else if (Subscriber.getStatus().contentEquals(
                                "SUSPENDED")) {
                            try {
                                String suspendedReason = userInfo
                                        .getString("suspendreason");
                                if (suspendedReason != null
                                        && suspendedReason
                                                .contentEquals("NO_SUBSCRIPTION")) {

                                    new AlertDialog.Builder(getActivity())
                                            .setIcon(
                                                    android.R.drawable.ic_dialog_alert)
                                            .setTitle("Account Suspended")
                                            .setMessage(
                                                    "Your account doesn't have any active subscription. You need to subscribe to a Package before you can proceed.")
                                            .setPositiveButton(
                                                    "Subscribe",
                                                    new DialogInterface.OnClickListener() {
                                                        public void onClick(
                                                                DialogInterface dialog,
                                                                int which) {
                                                            recreatePackage();
                                                        }
                                                    })
                                            .setNegativeButton("Cancel", null)
                                            .show();

                                } else {
                                    // TODO
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                        } else if (Subscriber.getStatus().contentEquals("INIT")) {
                            // TODO
                        }
                    }
                }

                @Override
                public void onFailure(int statusCode,
                        org.apache.http.Header[] headers, String responseBody,
                        Throwable e) {
                    super.onFailure(statusCode, headers, responseBody, e);
                    String msg = getActivity().getResources().getString(
                            R.string.loginFailure)
                            + "\nError: " + responseBody;
                    tvLoginFailure.setText(msg);
                    tvLoginFailure.setVisibility(View.VISIBLE);
                }
            });
morten.c
  • 3,414
  • 5
  • 40
  • 45
r4jiv007
  • 2,974
  • 3
  • 29
  • 36

4 Answers4

23

You need import the public server certificate into your default keystore, or if you are not interested in the authentication of your client you can initialize the AsyncHttpClient with

AsyncHttpClient asycnHttpClient = new AsyncHttpClient(true, 80, 443);

but this trick is not secure because use a custom SSLSocketFactory implementation whos omit the SSL certificate validation, take a look at the AsyncHttpClient source code.

More information about SSLSocketFactory at https://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

vzamanillo
  • 9,905
  • 1
  • 36
  • 56
  • "You need import the public server certificate into your default keystore" can u give some links for that ? – r4jiv007 Feb 17 '14 at 17:01
  • 2
    You're welcome :), a good example https://stackoverflow.com/questions/20706026/bing-azure-search-api/20789379#20789379 – vzamanillo Feb 17 '14 at 17:02
  • SSLSocketFactory is deprecated. https://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory; Also, I tried the above code snippet and that did not work either. – Beezer Jul 01 '18 at 09:56
11

you can also solve this problem, with adding this 1 line.

asyncHttpClient.setSSLSocketFactory(MySSLSocketFactory.getFixedSocketFactory());
JavadKhan
  • 625
  • 6
  • 18
  • It is important to mention, when using MySSLSocketFactory: "Warning! This omits SSL certificate validation on every device, use with caution." – rbrisuda Jan 23 '17 at 13:41
  • 2
    This is a better solution than the previous above it. But it did not solve my issue unfortunately. I really like asyncHttpClient but this is now a blocker for me. Only alternative is for me to make sure the server cert is in my keystore. The call still initiates an SSL handshake and then it fails. I used the okHttp code generated by Postman, for the SAME https call, and it works. Go figure!!!! – Beezer Jul 01 '18 at 10:16
3

I have a simple http client that calls https service:

import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

/**
 */
public class HttpSimpleClient {

    private static final String TAG = HttpSimpleClient.class.getSimpleName();

    private static HttpSimpleClient instance;

    private HttpSimpleClient(){}

    public static HttpSimpleClient instance(){
        if (instance==null) {
            instance = new HttpSimpleClient();
        }
        return instance;
    }

    public <T> T post(URL url,
                      List<NameValuePair> header,
                      List<NameValuePair> parameter,
                      ResponseHandler<T> responseHandler) throws IOException {
        return post(url, header, parameter, responseHandler, null, null);
    }

    public <T> T post(URL url,
                     List<NameValuePair> header,
                     List<NameValuePair> parameter,
                     ResponseHandler<T> responseHandler,
                     AuthScope proxy,
                     UsernamePasswordCredentials proxyUser) throws IOException {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost request = new HttpPost(url.toString());

        if (header!=null) {
            for (NameValuePair head : header){
                request.setHeader(head.getName(), head.getValue());
            }
            Log.d(TAG, "Aggiunti header: "+ header.size());

        } else {
            // Header di default
            request.setHeader("Content-Type", "application/x-www-form-urlencoded");
            request.setHeader("User-Agent", System.getProperty("http.agent"));
            Log.d(TAG, "Aggiunti header di defautl");
        }

        if (parameter!=null) {
            request.setEntity(new UrlEncodedFormEntity(parameter, HTTP.UTF_8));
            Log.d(TAG, "Aggiunti parametri: "+ parameter.size());
        }


        if (proxy!=null) {
            if (proxyUser!=null) {
                ((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(proxy, proxyUser);

            } else {
                // TODO gestire proxy senza credenziali
                ((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(proxy, null);

            }
            Log.d(TAG, "Impostato Proxy per la connessione");
        }
        return httpClient.execute(request, responseHandler);
    }


    public static String httpResponseToString(HttpResponse httpResponse, int bufferSize) throws IOException {
        InputStream content = httpResponse.getEntity().getContent();

        int numRead;
        byte[] buffer = new byte[bufferSize];
        ByteArrayOutputStream outString = new ByteArrayOutputStream();
        try{
            while ((numRead = content.read(buffer)) != -1) {
                outString.write(buffer, 0, numRead);
            }
        } finally {
            content.close();
        }
        return new String(outString.toByteArray());
    }
}

And i use it in a AsyncTask:

response = HttpSimpleClient.instance().post(
                    getServiceURL(), // HTTPS url
                    mHeader, // List<NameValuePair>
                    mParameter, // List<NameValuePair>
                    getResponseHandler() // org.apache.http.client.ResponseHandler
            );

Tested on Android api>=10

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73
1

Here is my code:

private Map<String, String> mParams;

public void sendata(View v) throws JSONException {
    username = (EditText) findViewById(R.id.txtusername);
    password = (EditText) findViewById(R.id.txtpassword);

    final ProgressDialog pDialog = new ProgressDialog(this);
    pDialog.setMessage("Loading...");
    pDialog.show();
    JSONObject j = new JSONObject();
    j.put("password", password.getText());
    j.put("username", username.getText());
    j.put("Deviceid", 123456789);
    j.put("RoleId", 1);
    String url = Url;
    AsyncHttpClient client = new AsyncHttpClient();
    RequestParams params = new RequestParams();
    params.put("json", j.toString());
    client.post(url, params, new JsonHttpResponseHandler() {
        @SuppressLint("NewApi")
        public void onSuccess(JSONObject response) {
            pDialog.hide();
            JSONObject jsnObjct;
            try {
                JSONObject json = (JSONObject) new JSONTokener(response
                        .toString()).nextValue();
                JSONObject json2 = json.getJSONObject("Data");
                JSONArray test = (JSONArray) json2
                        .getJSONArray("PatientAllergies");
                for (int i = 0; i < test.length(); i++) {
                    json = test.getJSONObject(i);
                    System.out.print(json.getString("PatientId"));
                    System.out.print(json.getString("Id"));
                    System.out.print(json.getString("AllergyName"));
                    System.out.print(json.getString("Reaction"));
                    System.out.print(json.getString("OnSetDate"));
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        public void onFailure(int statusCode, Header[] headers, String res,
                Throwable t) {
            pDialog.hide();
        }
    });

}
JSONObject jsonObject;

private void parsejson(JSONObject response) {

    try {
        jsonObject = response;
        System.out.print(response.toString());
        JSONObject jsnObjct = jsonObject.getJSONObject("Data");
        System.out.print(jsonObject.toString());
        jsnObjct = jsnObjct.getJSONObject("PhysicianDetail");

        System.out.print(jsnObjct.toString());

    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
Artem Kulikov
  • 2,250
  • 19
  • 32
Rajesh Kumar
  • 602
  • 6
  • 20