当我在AWS API Gateway中尝试使用JBOSS RestEasyClient到我的API的简单GET请求时,我收到了SSLHandShakeException。那是我的代码:
public static void main(String[] args){
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target( "https://MYAPI_ID.execute-api.us-east-1.amazonaws.com/prod/proxy" );
Response response = target.request().get();
String value = response.readEntity( String. class );
System.out.println( value );
response.close();
}
我明白了:
Exception in thread "main" javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:436)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.get(ClientInvocationBuilder.java:159)
at com.contaazul.gov.core.TesteSimples.main(TesteSimples.java:20)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:533)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:401)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:178)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:304)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283)
... 3 more
此代码适用于其他网站,例如https://google.com/,我的API的网址与cURL,Python urllib2以及Java中的类似内容:System.out.println(org.apache.commons.io.IOUtils.toString(new URL("https://MYAPI_ID.execute-api.us-east-1.amazonaws.com/prod/proxy")));
我已经尝试过向密钥库添加证书(很多时候,很多方面),我认为如果证书是问题我无法通过IOUtils获得响应,对吧?
谢谢!
答案 0 :(得分:1)
您收到此错误,因为API网关使用SNI,并且所有客户端都应具有SNI支持才能访问它。
答案 1 :(得分:1)
我曾经见过的API Gateway的每个SSLHandShakeException都是由不支持SNI的客户端引起的。 API网关使用服务器名称指示(SNI)来使用一小组IP地址支持许多自定义域名,以避免必须为每个名称分配专用IP地址。因此,客户端必须支持SNI才能调用API网关托管的API。
答案 2 :(得分:0)
根据此问题:https://issues.jboss.org/browse/RESTEASY-1089, 您可以尝试以下方法解决httpclient-4.2.1中阻止SNI工作的错误:
ResteasyClient client =
new ResteasyClientBuilder()
.httpEngine(new URLConnectionEngine())
.build();
这应该在httpclient-4.3.2中修复。