2011-11-11 17 views
5

Mam powodzeniem stosowane this solution w android odpowiedzieć na https serwer akceptując wszystkie certyfikatypołączenia https z httpclient 4.1.2 daje org.apache.http.client.ClientProtocolException

Teraz próbuję to samo w JAVA, aby opublikować na serwerze https akceptującym wszystkie certyfikaty.

Zmodyfikowałem klasę EasySSLSocketFactory z powyższego adresu URL, ponieważ klasy SocketFactory, LayeredSocketFactory są przestarzałe w wersji httpclient 4.1.2. EasyX509TrustManager klasa z powyższego adresu URL pozostaje bez zmian. Oto EasySSLSocketFactory, które mam zmodyfikowane. Zaznaczam klasy, które zmodyfikowałem.

/* 
* Licensed to the Apache Software Foundation (ASF) under one 
* or more contributor license agreements. See the NOTICE file 
* distributed with this work for additional information 
* regarding copyright ownership. The ASF licenses this file 
* to you under the Apache License, Version 2.0 (the 
* "License"); you may not use this file except in compliance 
* with the License. You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, 
* software distributed under the License is distributed on an 
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
* KIND, either express or implied. See the License for the 
* specific language governing permissions and limitations 
* under the License. 
*/ 

import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocket; 
import javax.net.ssl.TrustManager; 

import org.apache.http.conn.ConnectTimeoutException; 
import org.apache.http.conn.scheme.SchemeSocketFactory; 
import org.apache.http.params.HttpConnectionParams; 
import org.apache.http.params.HttpParams; 


public class EasySSLSocketFactory implements SchemeSocketFactory 
{ 
    private SSLContext sslcontext = null; 

    private static SSLContext createEasySSLContext() throws IOException { 
      try { 
        SSLContext context = SSLContext.getInstance("TLS"); 
        context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null); 
        return context; 
      } catch (Exception e) { 
        throw new IOException(e.getMessage()); 
      } 
    } 


    private SSLContext getSSLContext() throws IOException { 
      if (this.sslcontext == null) { 
        this.sslcontext = createEasySSLContext(); 
      } 
      return this.sslcontext; 
    } 

    /** 
     * @see org.apache.http.conn.scheme.SchemeSocketFactory#isSecure(java.net.Socket) 
     */ 
    public boolean isSecure(Socket socket) throws IllegalArgumentException { 
      return true; 
    } 

    // ------------------------------------------------------------------- 
    // javadoc in org.apache.http.conn.scheme.SocketFactory says : 
    // Both Object.equals() and Object.hashCode() must be overridden 
    // for the correct operation of some connection managers 
    // ------------------------------------------------------------------- 

    public boolean equals(Object obj) { 
      return ((obj != null) && obj.getClass().equals(
          EasySSLSocketFactory.class)); 
    } 

    public int hashCode() { 
      return EasySSLSocketFactory.class.hashCode(); 
    } 

    //this method is modified 
    @Override 
    public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress, 
      InetSocketAddress localAddress, HttpParams params) throws IOException, 
      UnknownHostException, ConnectTimeoutException { 

     int connTimeout = HttpConnectionParams.getConnectionTimeout(params); 
     int soTimeout = HttpConnectionParams.getSoTimeout(params); 
     SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket(params)); 
     if (localAddress != null) { 
      // we need to bind explicitly 
      sslsock.bind(localAddress); 
    } 

    sslsock.connect(remoteAddress, connTimeout); 
    sslsock.setSoTimeout(soTimeout); 
    return sslsock; 
    } 

    //this method is modified 
    @Override 
    public Socket createSocket(HttpParams arg0) throws IOException { 
     return getSSLContext().getSocketFactory().createSocket(); 
    } 

} 

I tu jest moje httpclient.This klasa jest również zmodyfikowany z powodu korzystania httpclient 4.1.2

public class MyHttpClient extends DefaultHttpClient { 

    /** The time it takes for our client to timeout */ 
    public static final int HTTP_TIMEOUT = 30 * 1000; // milliseconds 
    public static final int SOCKET_TIMEOUT = 50 * 1000; // milliseconds 


    public MyHttpClient() { 
    } 

    @Override 
    protected ClientConnectionManager createClientConnectionManager() { 

     SchemeRegistry registry = new SchemeRegistry(); 
     registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); 
     // Register for port 443 our SSLSocketFactory to the ConnectionManager 
     registry.register(new Scheme("https", 443, new EasySSLSocketFactory())); 

     //setting the httpparams 
     HttpParams params = new BasicHttpParams(); 
     //params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 1); 
     //params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(1)); 
     params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false); 
     //HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, "utf8"); 

     return new SingleClientConnManager(registry); 
    } 

} 

próbuję podłączyć w następujący sposób

ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>(); 
     postParameters.add(new BasicNameValuePair("userid", userid)); 
     postParameters.add(new BasicNameValuePair("password", password)); 
     String newresponse = null; 
     BufferedReader in = null; 
     try{ 
      DefaultHttpClient client = new MyHttpClient(); 
      try {   
        HttpPost req = new HttpPost(my https url); 
        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters); 
        req.setEntity(formEntity); 
        HttpResponse resp = client.execute(req); 
        in = new BufferedReader(new InputStreamReader(resp.getEntity().getContent())); 
        StringBuffer sb = new StringBuffer(""); 
        String line = ""; 
        String NL = System.getProperty("line.separator"); 
        while ((line = in.readLine()) != null) { 
         sb.append(line + NL); 
        } 
        in.close(); 
        newresponse = sb.toString(); 

        }catch(Exception e){ 
         LOGGER.error("Exception", e); 
        }finally { 
         if (in != null) { 
          try { 
           in.close(); 
          } catch (IOException e) { 
           LOGGER.error("IOException: ",e); 
          } 
         } 
        } 
     } catch(Exception e){ 
      LOGGER.debug("Connection Exception: ",e); 
     } 

Kiedy spróbuj połączyć się z serwerem https w powyższy sposób, aby uzyskać

org.apache.http.client.ClientProtocolException 
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:822) 
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) 
     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:576) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
     at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399) 
     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317) 
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204) 
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:182) 
     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
     at java.lang.Thread.run(Thread.java:662) 
Caused by: org.apache.http.HttpException: Unable to establish route: planned = HttpRoute[{}->https://mysiteurlhere]; current = HttpRoute[{s}->https://mysiteurlhere] 
     at org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:774) 
     at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:577) 
     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) 
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
     ... 22 more 

Serwer, do którego próbuję uzyskać dostęp, korzysta z certyfikatu z verisign, którego nie mam ze mną. Dlatego próbuję zaakceptować wszystkie certyfikaty. W przyszłości zamierzam to zmienić.

Czy ktokolwiek może sprawić, żeby działało? Z góry dzięki.

Odpowiedz

4

Twój EasySSLSocketFactory musi również implementować interfejs LayeredSchemeSocketFactory, jeśli chcesz, aby wspierał tunelowanie SSL.

+0

@ oleg- Dzięki za response.I postara że i będziesz pisał. – Sreeram

+0

@ oleg- Próbowałem go wdrożyć i działa jak urok. Dziękuję bardzo – Sreeram

0

również trzeba zarejestrować Scheme dla SSLSockerFactory:

httpClient.getConnectionManager().getSchemeRegistry().register(
    new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory()) 
); 
Powiązane problemy