使用htaccess在https页面上使用android进行POST请求

时间:2013-05-12 14:51:22

标签: android post ssl

我一直在寻找各处,我发现的信息与我的情况无关。 有人可以帮助我吗: 我需要向具有Android应用程序的服务器上的特定URL发送POST请求。 目标页面使用https加密,受htaccess保护。 最后一件事:服务器侦听一个随机端口,如14000,在证书中,主机名与主机名的URL不同。 我知道这很有挑战性,但我尝试过的都没有用。 我可以试试这个:

private void process() {
    new Thread(new Runnable() {
        public void run() {
            String httpsURL = "https://login:password@z-cloud.z-wave.me/ZWaveAPI/Data/0";
            HttpResponse httpResponse;
            HttpPost httpQuery = new HttpPost(httpsURL);
            CustomHttpClient myClient = new CustomHttpClient(myContext);
            Log.v("exec", "ready...");
            try {
                httpResponse = myClient.execute(httpQuery);
                if (httpResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
                    Log.v("exec", "it works ?");
                }
                Log.v("exec", httpResponse.getStatusLine().getStatusCode()+"");
            } catch (Exception ex) {
                Log.d("httpError", ex.getMessage());
            }
        }
    }).start();
}

和CustomHttpClient类:

public class CustomHttpClient extends DefaultHttpClient {

private static Context appContext = null;
private static Scheme httpsScheme = null;
private static Scheme httpScheme = null;
private static String TAG = "MyHttpClient";

public CustomHttpClient(Context myContext) {

    appContext = myContext;

    if (httpScheme == null || httpsScheme == null) {
        httpScheme = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80);
        httpsScheme = new Scheme("https", mySSLSocketFactory(), 14000);
    }

    getConnectionManager().getSchemeRegistry().register(httpScheme);
    getConnectionManager().getSchemeRegistry().register(httpsScheme);

}

@SuppressWarnings("finally")
private SSLSocketFactory mySSLSocketFactory() {
    SSLSocketFactory ret = null;
    try {
        final KeyStore ks = KeyStore.getInstance("BKS");

        final InputStream inputStream = appContext.getResources().openRawResource(R.raw.certs);

        ks.load(inputStream, appContext.getString(R.string.store_pass).toCharArray());
        inputStream.close();
        ret = new SSLSocketFactory(ks);
        ret.setHostnameVerifier(myhostnameVerifier);
    } catch (UnrecoverableKeyException ex) {
        Log.d(TAG, ex.getMessage());
    } catch (KeyStoreException ex) {
        Log.d(TAG, ex.getMessage());
    } catch (KeyManagementException ex) {
        Log.d(TAG, ex.getMessage());
    } catch (NoSuchAlgorithmException ex) {
        Log.d(TAG, ex.getMessage());
    } catch (IOException ex) {
        Log.d(TAG, ex.getMessage());
    } catch (Exception ex) {
        Log.d(TAG, ex.getMessage());
    } finally {
        return ret;
    }
}

X509HostnameVerifier myhostnameVerifier = new X509HostnameVerifier() {

    @Override
    public void verify(String arg0, SSLSocket arg1) throws IOException {
        Log.v("X509", "verified "+arg0);
        if("z-cloud.z-wave.me" != arg0)
        {
            //throw new SSLException("Mismatching hostname");
        }
    }

    @Override
    public void verify(String arg0, X509Certificate arg1)
            throws SSLException {
        Log.v("X509", "called 2");
    }

    @Override
    public void verify(String arg0, String[] arg1, String[] arg2)
            throws SSLException {
        Log.v("X509", "called 3");
    }

    @Override
    public boolean verify(String host, SSLSession session) {
        Log.v("X509", "called 4");
        return false;
    }
};
}

我不知道为什么但是我收到错误401但是我登录并且密码很好。 我不确定我使用的证书是否正确,但我真的需要它吗? 请帮助我,我真的很累,试图发送简单的帖子请求......

1 个答案:

答案 0 :(得分:0)

实现此目的的最佳方法是使用包含服务器证书的自定义TrustStore。可能没有必要验证主机名 - 证书应该是所有需要的。

我不会尝试调试您的代码,而是会指向一篇博客文章,我之前做了一段时间,其中有一个完整的工作示例,说明如何执行此操作。看看http://blog.chariotsolutions.com/2013/01/https-with-client-certificates-on.html

编辑 - 该示例显示了如何使用您不需要的客户端证书 - 只需忽略该部分。