SSLHandShakeException to AWS API Gateway with ResteasyClient

SSLHandShakeException to AWS API Gateway with ResteasyClient

当我尝试使用 JBOSS RestEasyClient 向我在 AWS API 网关中的 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 的 URL 适用于 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 获得响应,对吧?

谢谢!

您收到此错误是因为 API 网关使用 SNI,并且所有客户端都应该支持 SNI 才能访问它。

我在 API 网关中看到的每个 SSLHandShakeException 都是由不支持 SNI 的客户端引起的。 API 网关使用服务器名称指示 (SNI) 来支持使用一小组 IP 地址的许多自定义域名,以避免必须为每个名称分配专用 IP 地址。因此,客户端必须支持 SNI 才能调用由 API 网关托管的 API。

每期:https://issues.jboss.org/browse/RESTEASY-1089, 您可以针对 httpclient-4.2.1 中阻止 SNI 工作的错误尝试以下解决方法:

ResteasyClient client =
   new ResteasyClientBuilder()
      .httpEngine(new URLConnectionEngine())
      .build();

这应该在 httpclient-4.3.2 中得到修复。