6

Microsoft の次の C# コードを使用して EWS 2010 MSDN リンクを要求したところ、機能しました。Androidにも同じソリューションが必要です。

次のコードを使用しようとしましたが、役に立ちません

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

ここに私のxmlリクエストがあります

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

キーストアでカスタム HttpsClient も使用します。

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

}

しかし、常に「接続タイムアウト」が表示され、何も応答しませ
ん。どこに問題があるのか​​教えてください。どんな例でも助けになるでしょう。前もって感謝します!

4

1 に答える 1

4

ニコライ・エレンコフに感謝!

最後に、解決策を見つけました。このリンクに従います: Android でのカスタム証明書信頼ストアの使用

まず、DefaultHttpClient代わりに使用しますHttpClient(メソッドcreateHttpClientWithDefaultSocketFactory()は である必要があります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);
    }
}

CredentialsProvider次に、認証用に追加します。

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

これで、うまく機能します!

于 2012-04-12T10:57:13.130 に答える