Request Exchange Web Services 2007/2010 with SOAP + XML over HTTPS on Android

I used the following C # code from Microsoft to request an EWS 2010 MSDN link and it worked. I need the same solution for Android.

I tried using the following code, but this does not help

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()); 

Here is my xml request

 <?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> 

I also use custom HttpsClient with 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; } 

}

But it always shows "connection timeout" and does not respond
Please tell me where is my problem? Any example is help. Thanks in advance!

+6
source share
1 answer

Many thanks to Nikolai Elenkov!

Finally, I found a solution. I follow this link: Using a specialized certificate store for certificates on Android

First I use DefaultHttpClient instead of HttpClient (the createHttpClientWithDefaultSocketFactory() method should be 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); } } 

Then I add CredentialsProvider for authentication.

  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); 

Now it can work well!

+4
source

Source: https://habr.com/ru/post/912725/


All Articles