2012-09-21 15 views
5

自分の実装したJava Webプロキシ(実際のWebサービスへのリクエストを転送する)とAndroidアプリケーションの間に安全なWebサービスを開発しています。Android HttpClientとのSSL接続の再利用

標準(安全でない)HTTP接続を使用すると、正常に動作します。今私は、プロキシとアンドロイドクライアントの間に安全な(SSL)接続を使用したいと思います。

これは、リクエストごとに新しいHttpClientをインスタンス化する限り動作します。これは、リクエストごとに2つのハンドシェイクを実行しているため、非常に低速なリソースの浪費です。

だから私は、次の例外

java.lang.IllegalStateExceptionでセキュアな接続のために結果要求ごとのHttpClientを再利用しようとしています。Connectionすでにオープン。 at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) at org.apache。 http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) (org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)) (org.apache.http.impl.client) org.apache.http.impl.client.AbstractHttpClient.executeでAbstractHttpClient.execute(AbstractHttpClient.java:487) (AbstractHttpClient.java:465)

ノーSSLに私のプロキシとクライアントを変更

それは問題なく動作します。 誰かが私が間違っていることを知っていますか?あなたの助けをありがとう!

ところで、ServerSocketを使用する代わりに、ロードされた証明書でSSLServerSocketを使用する点を除いて、サーバーコードは完全に似ています。

クライアントのパラメータ設定

// Set basic data 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, "UTF-8"); 
    HttpProtocolParams.setUseExpectContinue(params, true); 
    HttpProtocolParams.setUserAgent(params, "Android app/1.0.0"); 

    // Make pool 
    ConnPerRoute connPerRoute = new ConnPerRouteBean(12); 
    ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute); 
    ConnManagerParams.setMaxTotalConnections(params, 20); 

    // Set timeout 
    HttpConnectionParams.setStaleCheckingEnabled(params, false); 
    HttpConnectionParams.setConnectionTimeout(params, connectionTimeoutMillis); 
    HttpConnectionParams.setSoTimeout(params, socketTimeoutMillis); 
    HttpConnectionParams.setSocketBufferSize(params, 8192); 

    // Some client params 
    HttpClientParams.setRedirecting(params, false); 

HTTPクライアントの作成

// load truststore certificate 
      InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.server); 
      KeyStore trustStore = KeyStore.getInstance("BKS"); 
      trustStore.load(clientTruststoreIs, "server".toCharArray()); 

      // initialize trust manager factory with the read truststore 
      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      trustManagerFactory.init(trustStore); 

      // setup client certificate 

      // load client certificate 
      InputStream keyStoreStream = context.getResources().openRawResource(R.raw.client); 
      KeyStore keyStore = KeyStore.getInstance("BKS"); 
      keyStore.load(keyStoreStream, "client".toCharArray()); 

      // initialize key manager factory with the read client 
      // certificate 
      KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
      keyManagerFactory.init(keyStore, "client".toCharArray()); 

      // initialize SSLSocketFactory to use the certificates 
      SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "client", trustStore, null, null); 

      // Register http/s shemas! 
      SchemeRegistry schReg = new SchemeRegistry(); 
      schReg.register(new Scheme("https", socketFactory, port)); 
      ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); 

      httpClient = new DefaultHttpClient(conMgr, params); 

クライアント要求の実行

HttpResponse response = httpClient.execute(request); 
     HttpEntity entity = response.getEntity(); 
     in = entity.getContent(); 
     String result = convertStreamToString(in); 
     in.close(); 

答えて

0

あなたはスレッドセーフな接続マネージャを使用していますか?そうでない場合は、複数のスレッドで同じHttpClientを使用している場合は問題になる可能性があります。

この記事は、詳細があります。http://candrews.integralblue.com/2011/09/best-way-to-use-httpclient-in-android/

+0

あなたの答えをありがとう。はい、あなたは私が提供したコードで見ることができます。別のスレッドから使​​用されていても、SSLを使用せずに使用すると、コードは正常に動作します。しかし、私はSSLに変更すると、例外が上に壊れます。その他の提案はありますか? – user1033552

3

私はAndroidとのHttpClientでこれと同じ問題がある - あなたが持っているだけのように、クライアント側の証明書を使用するときに現れるようです。クライアント認証を削除しても正常に動作し、まだ回避策が見つかりませんでした。

編集:

無効な接続チェックを有効にします。

HttpConnectionParams.setStaleCheckingEnabled(params、true);

私のために修正されました。

+0

Thx。これは、クライアント証明書が有効になっている場合にのみ発生することを確認できます。これは私のためにも修正されました。 – icyerasor