在Android中使用RestTemplate使用https REST WebService

时间:2017-01-27 21:46:57

标签: java android rest ssl resttemplate

在我的服务器中,我实现了自签名证书,并且我已经使用REST端点公开了一些方法。我的客户端是一个Android设备,我想从中使用Spring RestTemplate来使用端点。问题是我使用的是https和自签名证书。我正在关注official android ssl guide以便我的应用程序能够成功连接到我的服务器的根目录,但是当我点击端点进行登录时,它会产生异常。

我的应用代码:

   try {

            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
            VoterReply voterReply = restTemplate.getForObject(RESTURL + LOGIN+"?username="+username+"&password="+password, VoterReply.class);
            return voterReply;
        }
        catch (Exception e){
            Log.e("NFCLOGIN",e.getMessage(),e);
        }

异常:

E/NFCLOGIN: I/O error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.; nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        org.springframework.web.client.ResourceAccessException: I/O error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.; nested exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
            at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:491)
            at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
            at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:372)
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:364)
            at android.os.AsyncTask$2.call(AsyncTask.java:295)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)
         Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328)
            at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
            at com.android.okhttp.Connection.connect(Connection.java:143)
            at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
            at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
            at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:342)
            at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:331)
            at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:249)
            at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
            at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
            at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
            at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:25)
            at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:72)
            at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
            at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63)
            at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:476)
            at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439) 
            at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237) 
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:372) 
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:364) 
            at android.os.AsyncTask$2.call(AsyncTask.java:295) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
            at java.lang.Thread.run(Thread.java:818) 
         Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
            at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:324)
            at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:225)
            at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
            at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:556)
            at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
            at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103) 
            at com.android.okhttp.Connection.connect(Connection.java:143) 
            at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185) 
            at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) 
            at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:342) 
            at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:331) 
            at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:249) 
            at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437) 
            at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114) 
            at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89) 
            at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:25) 
            at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:72) 
            at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46) 
            at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63) 
            at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:476) 
            at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439) 
            at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237) 
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:372) 
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:364) 
            at android.os.AsyncTask$2.call(AsyncTask.java:295) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
            at java.lang.Thread.run(Thread.java:818) 
         Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
            at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:324) 
            at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:225) 
            at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115) 
            at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:556) 
            at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324) 
            at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103) 
            at com.android.okhttp.Connection.connect(Connection.java:143) 
            at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185) 
            at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) 
            at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:342) 
            at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:331) 
            at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:249) 
            at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437) 
            at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114) 
            at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89) 
            at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:25) 
            at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:72) 
            at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46) 
            at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63) 
            at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:476) 
            at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439) 
            at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237) 
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:372) 
            at evoting.marios.com.evoting.NfcLogin$HttpRequestTask.doInBackground(NfcLogin.java:364) 
            at android.os.AsyncTask$2.call(AsyncTask.java:295) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
            at java.lang.Thread.run(Thread.java:818) 

1 个答案:

答案 0 :(得分:0)

如果在连接时添加SSL证书,则可以执行此操作

首先下载/获取您的证书文件'your_cert.crt'并将其粘贴到您的res / raw文件夹中(如果需要,创建原始文件夹)。 (您可以使用firefox浏览器下载证书)

我建议使用okhttp客户端。 添加您的应用程序gradle文件:

compile 'com.squareup.okhttp:okhttp:2.5.0'

这里是使用可信证书创建okhttp客户端的代码。它使用证书创建一个密钥库,并将其与TrustManagerFactory对象一起使用以初始化SSLContext:

public static OkHttpClient createClient(Context context) {

    OkHttpClient client = null;

    CertificateFactory cf = null;
    InputStream cert = null;
    Certificate ca = null;
    SSLContext sslContext = null;
    try {
        cf = CertificateFactory.getInstance("X.509");
        cert = context.getResources().openRawResource(R.raw.your_cert); // Place your 'your_cert.crt' file in `res/raw`

        ca = cf.generateCertificate(cert);
        cert.close();

        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        clientBuilder.connectTimeout(10, TimeUnit.SECONDS);
        clientBuilder.writeTimeout(10, TimeUnit.SECONDS);
        clientBuilder.readTimeout(30, TimeUnit.SECONDS);

        client = clientBuilder.sslSocketFactory(sslContext.getSocketFactory()).build();



    } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException | KeyManagementException e) {
        e.printStackTrace();
    }

    return client;
}

并在您的活动中:

OkHttpClient client = createClient(context);
ClientHttpRequestFactory requestFactory = new OkHttpClientHttpRequestFactory(client);
RestTemplate restTemplate = new RestTemplate(requestFactory);