2012-04-09 37 views
6

Tôi đã sử dụng mã C# sau từ Microsoft để yêu cầu EWS 2010 MSDN link và nó hoạt động. Tôi cần giải pháp tương tự cho android.Yêu cầu Dịch vụ Web Exchange 2007/2010 với SOAP + XML qua HTTPS trong Android

Tôi cố gắng để sử dụng đoạn mã sau nhưng nó không giúp

DefaultHttpClient client = new HttpsClient(
       MyActivity.this); 

     requestBytes = myXMLStringRequest.getBytes("UTF-8"); 

     HttpPost httpPost = new HttpPost(url); 
     httpPost.setHeader("Content-Type", "text/xml;utf-8"); 
     if (requestBytes != null) { 
      httpPost.setHeader("Content-length", 
        String.valueOf(requestBytes.length)); 
      Log.d(TAG, "content length: " + requestBytes.length); 
     } 

     client.getCredentialsProvider().setCredentials(
       new AuthScope(url, 443), 
       new UsernamePasswordCredentials(userName, 
         password)); 
     Log.d(TAG, "Begin request"); 
     HttpResponse response = client.execute(httpPost); 
     Log.d(TAG, "status Line: " + response.getStatusLine().toString()); 

Đây là yêu cầu xml tôi

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" 
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> 
<soap:Body> 
<GetFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"    xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> 
<FolderShape>  
    <t:BaseShape>Default</t:BaseShape> 
</FolderShape>  
<FolderIds>  
    <t:DistinguishedFolderId Id="inbox"/>  
    <t:DistinguishedFolderId Id="deleteditems"/> 
</FolderIds> 
</GetFolder> 

tôi cũng sử dụng tùy chỉnh HttpsClient với keystore.

public class HttpsClient extends DefaultHttpClient { 
private final Context context; 

public HttpsClient(final Context context) { 
    super(); 
    this.context = context; 
} 

/** 
* The method used to create client connection manager 
*/ 
@Override 
protected ClientConnectionManager createClientConnectionManager() { 
    final SchemeRegistry registry = new SchemeRegistry(); 
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 8080)); 

    // Register for port 443 our SSLSocketFactory with our keystore 
    // to the ConnectionManager 
    registry.register(new Scheme("https", newSslSocketFactory(), 8443)); 
    return new SingleClientConnManager(getParams(), registry); 
} 

private SSLSocketFactory newSslSocketFactory() { 
    try { 
     // Get an instance of the Bouncy Castle KeyStore format 
     final KeyStore trusted = KeyStore.getInstance("BKS"); 
     // Get the raw resource, which contains the keystore with 
     // your trusted certificates (root and any intermediate certs) 
     final InputStream inputStream = context.getResources().openRawResource(R.raw.parkgroup_ws_client); 
     try { 
      // Initialize the keystore with the provided truste 
      // certificates 
      // Also provide the password of the keystore 
      trusted.load(inputStream, "myKeyStorePassword".toCharArray()); 
     } finally { 
      inputStream.close(); 
     } 
     // Pass the keystore to the SSLSocketFactory. The factory is 
     // responsible 
     // for the verification of the server certificate. 
     final SSLSocketFactory ssf = new SSLSocketFactory(trusted); 
     // Hostname verification from certificate 
     // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 
     ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
     return ssf; 
    } catch (Exception e) { 
     Log.e("MYTAG", e.getMessage()); 
     throw new AssertionError(e); 
    } 
} 

@Override 
protected HttpParams createHttpParams() { 
    final HttpParams httpParams = super.createHttpParams(); 
    httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000); 
    httpParams.setParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false); 
    return httpParams; 
} 

}

Nhưng nó luôn luôn hiển thị "connect timeout" và không đáp ứng bất cứ điều gì
Hãy cho tôi biết đâu là vấn đề của tôi? Bất kỳ ví dụ nào cũng sẽ hữu ích. Cảm ơn bạn trước!

+0

Máy chủ của bạn có hỗ trợ giao thức TLS không? Có lỗi trong Android mà nó không kết nối được với một số máy chủ không được kích hoạt TLS. –

+0

Vâng, đúng vậy. Tôi không biết vấn đề của tôi ở đâu, nó luôn luôn hết thời gian chờ – R4j

Trả lời

4

Rất cám ơn Nikolay Elenkov!

Cuối cùng, tôi đã tìm thấy giải pháp. Tôi đi theo liên kết này: Using a Custom Certificate Trust Store on Android

Trước tiên, tôi sử dụng DefaultHttpClient thay vì HttpClient (phương pháp createHttpClientWithDefaultSocketFactory() nên return DefaultHttpClient):

private DefaultHttpClient createHttpClientWithDefaultSocketFactory(
     KeyStore keyStore, KeyStore trustStore) { 
    try { 
     SSLSocketFactory sslSocketFactory = SSLSocketFactory 
       .getSocketFactory(); 
     if (keyStore != null && trustStore != null) { 
      sslSocketFactory = new SSLSocketFactory(keyStore, 
        KEYSTORE_PASSWORD, trustStore); 
     } else if (trustStore != null) { 
      sslSocketFactory = new SSLSocketFactory(trustStore); 
     } 

     return createHttpClient(sslSocketFactory); 
    } catch (GeneralSecurityException e) { 
     throw new RuntimeException(e); 
    } 
} 

Sau đó, tôi thêm CredentialsProvider để xác thực.

DefaultHttpClient client = createHttpClientWithDefaultSocketFactory(
       keyStore, trustStore); 
     HttpPost httpPost = new HttpPost(SERVER_AUTH_URL); 
     httpPost.setHeader("Content-type", "text/xml;utf-8"); 

     StringEntity se = new StringEntity(builder.toString(), "UTF8"); 
     se.setContentType("text/xml"); 
     httpPost.setEntity(se); 
     CredentialsProvider credProvider = new BasicCredentialsProvider(); 

     credProvider.setCredentials(new AuthScope(URL, 
       443), new UsernamePasswordCredentials(USERNAME, password)); 

     // This will exclude the NTLM authentication scheme 

     client.setCredentialsProvider(credProvider); 
     HttpResponse response = client.execute(httpPost); 

Bây giờ, nó có thể hoạt động tốt!

Các vấn đề liên quan