我想发送给使用HttpsURLConnection的类服务器的请求。 该服务器证书的问题,所以我成立了一个的TrustManager一个信任的一切,以及主机名验证者同样是宽松的。 当我提出我的要求直接,但它似乎并没有在所有使用的时候我送通过代理请求这位经理的工作就好了。
我这样设置我的代理服务器设置:
Properties systemProperties = System.getProperties();
systemProperties.setProperty( "http.proxyHost", "proxyserver" );
systemProperties.setProperty( "http.proxyPort", "8080" );
systemProperties.setProperty( "https.proxyHost", "proxyserver" );
systemProperties.setProperty( "https.proxyPort", "8080" );
默认的SSLSocketFactory的的TrustManager设置是这样的:
SSLContext sslContext = SSLContext.getInstance( "SSL" );
// set up a TrustManager that trusts everything
sslContext.init( null, new TrustManager[]
{
new X509TrustManager()
{
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
public void checkClientTrusted( X509Certificate[] certs, String authType )
{
// everything is trusted
}
public void checkServerTrusted( X509Certificate[] certs, String authType )
{
// everything is trusted
}
}
}, new SecureRandom() );
// this doesn't seem to apply to connections through a proxy
HttpsURLConnection.setDefaultSSLSocketFactory( sslContext.getSocketFactory() );
// setup a hostname verifier that verifies everything
HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier()
{
public boolean verify( String arg0, SSLSession arg1 )
{
return true;
}
} );
如果我运行下面的代码,我结束了一个SSLHandshakException(“远程主机关闭握手期间连接”):
URL url = new URL( "https://someurl" );
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setDoOutput( true );
connection.setRequestMethod( "POST" );
connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
connection.setRequestProperty( "Content-Length", "0" );
connection.connect();
我想我是缺少某种具有与SSL打交道时使用的是代理做设定。 如果我不使用代理,我checkServerTrusted方法被调用; 这正是我需要的时候出现,我会通过代理为好。
我通常不会处理Java和我没有与HTTP /网络的东西太多经验。 我相信我已经提供了所有必要的细节,以了解我试图做的。 如果不是这种情况,让我知道。
更新:
通过读取编码器ZZ建议的文章后,我做了如下修改连接代码:
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
connection.setSSLSocketFactory( new SSLTunnelSocketFactory( proxyHost, proxyPort ) );
connection.setDoOutput( true );
connection.setRequestMethod( "POST" );
connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
connection.setRequestProperty( "Content-Length", "0" );
connection.connect();
结果(出现SSLHandshakeException)是相同的。 当我在这里设置SLLSocketFactory到SSLTunnelSocketFactory(类在文章中解释),我用的TrustManager和的SSLContext做的东西被覆盖。 难道我还需要什么?
另一个更新:
我修改了SSLTunnelSocketFactory类使用该使用我的TrustManager一个信任一切的SSLSocketFactory。 它不会出现,这已经作出任何区别。 这是SSLTunnelSocketFactory的方法的createSocket:
public Socket createSocket( Socket s, String host, int port, boolean autoClose )
throws IOException, UnknownHostException
{
Socket tunnel = new Socket( tunnelHost, tunnelPort );
doTunnelHandshake( tunnel, host, port );
SSLSocket result = (SSLSocket)dfactory.createSocket(
tunnel, host, port, autoClose );
result.addHandshakeCompletedListener(
new HandshakeCompletedListener()
{
public void handshakeCompleted( HandshakeCompletedEvent event )
{
System.out.println( "Handshake finished!" );
System.out.println(
"\t CipherSuite:" + event.getCipherSuite() );
System.out.println(
"\t SessionId " + event.getSession() );
System.out.println(
"\t PeerHost " + event.getSession().getPeerHost() );
}
} );
result.startHandshake();
return result;
}
当我的代码调用connection.connect,这种方法被调用,调用doTunnelHandshake是成功的。 接下来的代码行使用我的SSLSocketFactory创建的SSLSocket; 此调用后结果的toString值是:
“1d49247 [SSL_NULL_WITH_NULL_NULL:插座[ADDR = / ProxyHost的,端口= proxyPort,将localPort = 24372]]”。
这是毫无意义的我,但它可能是东西打破后这样做的原因。
当result.startHandshake()被调用时,相同的createSocket方法是从再次调用,根据调用堆栈,HttpsClient.afterConnect,使用相同的参数,除了插座S为空,并且当它涉及到周围result.startHandshake()再次,结果是一样的出现SSLHandshakeException。
我仍然缺少一个重要的一块这个日益复杂的难题?
这是堆栈跟踪:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123) at gsauthentication.SSLTunnelSocketFactory.createSocket(SSLTunnelSocketFactory.java:106) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:391) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133) at gsauthentication.GSAuthentication.main(GSAuthentication.java:52) Caused by: java.io.EOFException: SSL peer shut down incorrectly at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789) ... 8 more