2013-05-12 98 views
0

我一直在寻找相当无处不在,我发现的信息并未与我的案例一起工作。 有人可以帮我请这个: 我需要发送一个POST请求到一个具有Android应用程序的服务器上的特定网址。 目标页面正在使用https加密,并受htaccess保护。 最后一件事:服务器在像14000这样的随机端口上侦听,在证书中,主机名与主机名的url不同。 我知道这是相当具有挑战性的,但我没有尝试过。 Curently我试试这个:使用android在https页面上使用htaccess的POST请求

private void process() { 
    new Thread(new Runnable() { 
     public void run() { 
      String httpsURL = "https://login:[email protected]/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但m'y登录名和密码都不错。 我不太确定我使用的证书是否正确,但是我真的需要它吗? 请帮我,我真的很累试图发送一个简单的发布请求...

回答

0

最好的办法是使用包含服务器证书的自定义信任库。验证主机名可能没有必要 - 证书应该是所有需要的。

与其试图调试您的代码,我会告诉您一个博客文章,我做了一段时间后,有一个完整的工作示例如何执行此操作。看看http://blog.chariotsolutions.com/2013/01/https-with-client-certificates-on.html

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

+0

嗨!感谢您的帮助 !我设法通过你的帖子连接到服务器,但是我不得不添加一些我忘记的东西:身份验证头和base64加密中的情侣登录/密码。感谢您的回复! – 2013-05-12 18:42:59