2013-05-20 76 views
1

我正通過HTTPS連接到服務器。我接受來自服務器的所有x509證書。現在我只需要向httpclient添加認證用戶名和密碼。我使用HTTPClient而不是DefaultHTTPClient。所有代碼被列舉如下:Android:HTTPClient的HTTPS身份驗證用戶名和密碼

發送文件用了HTTPClient:

protected void sendFile(String url, File file) 
{ 
    try 
    { 
     HttpClient httpclient = new DefaultHttpClient(); 

     httpclient = sslClient(httpclient); 

     CredentialsProvider credProvider = new BasicCredentialsProvider(); 
     credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
      new UsernamePasswordCredentials("YOUR USER NAME HERE", "YOUR PASSWORD HERE")); 

     ((AbstractHttpClient) httpclient).setCredentialsProvider(credProvider); 

     HttpPost httppost = new HttpPost(url); 

     InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(file), -1); 
     reqEntity.setContentType("binary/octet-stream"); 
     reqEntity.setChunked(true); // Send in multiple parts if needed 
     httppost.setEntity(reqEntity); 

     HttpResponse response = httpclient.execute(httppost); 
     int status = response.getStatusLine().getStatusCode(); 
     // Do something with response... 
     Log.d(CLASSNAME, "Response: " + Integer.toString(status) + response.toString()); 

    } 
    catch(Exception e) 
    { 
     Log.e(CLASSNAME, "Caught exception: " + e.getMessage()); 
     e.printStackTrace(); 
    } 
} 

private HttpClient sslClient(HttpClient client) { 
    try { 
     X509TrustManager tm = new X509TrustManager() { 
      public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { 
      } 

      public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { 
      } 

      public X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 
     }; 
     SSLContext ctx = SSLContext.getInstance("TLS"); 
     ctx.init(null, new TrustManager[]{tm}, null); 
     SSLSocketFactory ssf = new MySSLSocketFactory(ctx); 
     ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
     ClientConnectionManager ccm = client.getConnectionManager(); 
     SchemeRegistry sr = ccm.getSchemeRegistry(); 
     sr.register(new Scheme("https", ssf, 443)); 
     return new DefaultHttpClient(ccm, client.getParams()); 
    } catch (Exception ex) { 
     return null; 
    } 
} 

該類接受的證書:

import java.io.IOException; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.UnrecoverableKeyException; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 
import org.apache.http.conn.ssl.SSLSocketFactory; 

public class MySSLSocketFactory extends SSLSocketFactory { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
    super(truststore); 

    TrustManager tm = new X509TrustManager() { 

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

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

     public X509Certificate[] getAcceptedIssuers() { 
      return null; 
     } 
    }; 

    sslContext.init(null, new TrustManager[] { tm }, null); 
} 

public MySSLSocketFactory(SSLContext context) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { 
    super(null); 
    sslContext = context; 
} 

@Override 
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { 
    return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); 
} 

@Override 
public Socket createSocket() throws IOException { 
    return sslContext.getSocketFactory().createSocket(); 
} 
} 

我得到以下異常:

org.apache.http.client.ClientProtocolException 

任何理由爲什麼?

+0

看我不知道關於你的情況,但是我們在Android上遇到了一個https問題,唯一適用於所有版本的是SSLSocket。出於某種原因,Apache和Java客戶端根本不想工作。它沒有妥善記錄,它有很多問題,所以祝你好運。 –

回答

0

我不確定你的問題到底是什麼,但看看this blog entry,我在後面展示瞭如何在Android上執行HTTPS,包括如何接受自簽名服務器證書而不只是盲目接受所有證書。

編輯:要使用HttpURLConnection類(如博客文章的例子中)做基本驗證,你會做與連接如下:

String encoded = Base64.encode(username+":"+password); 
connection.setRequestProperty("Authorization", "Basic "+encoded); 

參見Preemptive Basic Auth with HttpUrlConnection?

+0

我相信它與HttpClient httpclient = new DefaultHttpClient();因爲它沒有setCredentialProvider方法,所以我必須投射HTTPClient。 – wwjdm

+0

另外,你將如何添加身份驗證 – wwjdm

+0

你的實際答案不應該是一個博客文章的鏈接(現在已經被打破),如果你不能鏈接你可能會發表評論。 –

相關問題