gpt4 book ai didi

java - 在 Android 中使用 RestTemplate 使用 https REST WebService

转载 作者:太空宇宙 更新时间:2023-11-03 13:35:26 26 4
gpt4 key购买 nike

在我的服务器中,我实现了一个自签名证书,并且公开了一些使用 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) 

最佳答案

如果您在连接时添加 SSL 证书,则可以做到这一点

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

我推荐使用okhttp客户端。添加到您的应用程序 gradle 文件中:

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

这里是使用可信证书创建 okhttp 客户端的代码。它使用证书创建一个 keystore ,并将其与 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;
}

在你的 Activity 中:

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

关于java - 在 Android 中使用 RestTemplate 使用 https REST WebService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41903540/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com