据说这两天腾讯的服务器出了问题,认证的时候报这样的错:
oauth.signpost.exception.OAuthCommunicationException: Communication with the service provider failed: Not trusted server certificate Caused by: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
oauth.signpost.exception.OAuthCommunicationException: Communication with the service provider failed: Nopeer certificate
这是因为Https认证被截获导致,Client认为安全失效,很久之前就出现了这个问题了,那时候在WebView上加上下面的代码就可以解决了
public
void
onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); }
没想到又出现这个问题,于是一翻研究,在stackoverflow.com上找到答案,写了一个自定义类继承SSLSocketFactory
public
class SSLSocketFactoryEx
extends
SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"
);
public
SSLSocketFactoryEx(KeyStore truststore)
throws
NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super
(truststore); TrustManager tm =
new
X509TrustManager() {
public
java.security.cert.X509Certificate[] getAcceptedIssuers() {
return
null
; } @Override
public
void
checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType)
throws
java.security.cert.CertificateException { } @Override
public
void
checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType)
throws
java.security.cert.CertificateException { } }; sslContext.init(
null,
new TrustManager[] { tm },
null
); } @Override
public Socket createSocket(Socket socket, String host,
int
port,
boolean autoClose)
throws
IOException, UnknownHostException {
return
sslContext.getSocketFactory().createSocket(socket, host, port,autoClose); } @Override
public Socket createSocket()
throws
IOException {
return
sslContext.getSocketFactory().createSocket(); } } 调用方法,只要用认证返回的HttpCilent即可。代码:Java 代码复制内容到剪贴板
public
HttpClient getNewHttpClient() {
try
{ KeyStore trustStore =
KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(
null,
null
); SSLSocketFactory sf =
new
SSLSocketFactoryEx(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpParams params =
new
BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); SchemeRegistry registry =
new
SchemeRegistry(); registry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80
)); registry.register(
new Scheme("https", sf, 443
)); ClientConnectionManager ccm =
new
ThreadSafeClientConnManager(params, registry);
return
new
DefaultHttpClient(ccm, params); }
catch
(Exception e) {
return
new
DefaultHttpClient(); } }
这样就解决了问题,有网友说把腾讯认证的地址https去掉改成http,那是不可取的做法。
我已经把代码集成到signpost中,如果有需要的同学可自行下载,有不明白或者不好的地方给我评论留言。
源代码下载:http://06peng.com/read.php/60.htm
原文链接: http://www.cnblogs.com/vus520/archive/2012/04/12/2561977.html