JSP/SERVLET
2018.03.31 / 16:22

HttpComponents (HttpClient 4.x)에서 HTTPS 서버 연동하기

봄이
추천 수 47

예전 제가 외부 시스템과 연동할때는 대부분이 TCP/IP 기반 Socket 통신을
했었습니다.
지금 생각 하면 말도 안되는 인터페이스 메세지 설계하고, 
나 홀로 파서를 만들었죠.개발 년차가 있으신분들은 이해를 하실듯 .. 
^^하지만 최근에는 안드로이드, 아이폰등 앱 어플리케이션 과 
웹 서비스간의 다양한매쉬업으로 인해서 대부분 통신이 TCP/IP 기반 
HTTP 통신이 주를 이루고 있습니다.특히 내부/외부 시스템 간에 통신 방식도
HTTP 통신이 거의 일반화로 자리를 잡아가는듯 합니다.그중에서 없어서는 안될
라이브러리가 바로 Apache HttpClient 입니다.

이런 이유에서인지 최근(?) 
4.x로 되면서 더이상 Apache Commons의 서브 프로젝트가 아닌, 
Top Project로 승격이 되었고 이름도 “Apache Components”라고 
명칭 변경도 되었죠.물론 JDK에서 제공하는 라이브러리도 있지만, 심플하면서,
다양한 기능은역시 HttpClient라고 할 수 있습니다. 단순 “http://” 통신은
예제도 많고 심플한데, SSL 통신을 해야 할경우(개인 정보를 파라미터 전송할 경우)
생각 보다는 심플하지가 않더군요. ㅡ.ㅡ거기다가 테스트를 하기 위해서
WAS 또는 Web Server에 SSL 설정을해야하는 번거러움도 있죠….
더군다나 veriSing 같은 CA (Certificate Authority ) 발급하는 경우는
SSL 통신 방식또한 다소 틀려서 테스트하기가더욱 쉽지 않습니다.
하지만 다행히 CA 인증서를 받은 테스트 웹사이트가 있습니다. 
그래서 테스트 웹사이트 와 HttpClient 모듈을 이용해서 보다 쉽고,
편하게 “https://” 테스트 및 샘플코드에 대해서 말씀 드리겠습니다.
본 포스팅은 Android 개발자분들에게 더 도움이 많이 될 것 같으니꼭
참고 하시기 바랍니다.

  • 선행 조건

아래와 같이 메이븐 설정을 하시면 됩니다.

<dependency> 
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>       
  <version>4.1</version>   
  <type>jar</type>   
  <scope>compile</scope>
</dependency>

  • HTTPS 테스트 웹페이지

테스트 웹사이트 정보는 아래와 같습니다.
접속 URL : https://msp.f-secure.com/web-test/common/test.html

접속 Port : 443 (ssl 기본 포트)

image

  • HttpClient로 접속 하기

package org.beyondj2ee;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

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

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class HttpsTest {

    /-*
     * @param args
     *-
    public static void main(String[] args) throws Exception {
        DefaultHttpClient httpclient = new DefaultHttpClient();

        TrustManager easyTrustManager = new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                // no-op
                return null;
            }

            public void checkServerTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
            }

            public void checkClientTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
            }
        };

        try {
            SSLContext sslcontext = SSLContext.getInstance(“TLS”);
            sslcontext
                    .init(null, new TrustManager[] { easyTrustManager }, null);

            SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext,
                    SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);

//            SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext,
//                    SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            
            Scheme sch = new Scheme(“https”, 443, socketFactory);
            httpclient.getConnectionManager().getSchemeRegistry().register(sch);

            HttpGet httpget = new HttpGet(
                    “https://msp.f-secure.com/web-test/common/test.html”);

            System.out.println(“executing request” + httpget.getRequestLine());

            HttpResponse response = httpclient.execute(httpget);

            HttpEntity entity = response.getEntity();

            String responseBody = EntityUtils.toString(response.getEntity(),
                    “UTF-8”);

            System.out.println(responseBody);

            System.out.println(“—————————————-”);
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println(“Response content length: ”
                        + entity.getContentLength());
            }
            EntityUtils.consume(entity);

        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
}

    만약 본인 인증 방식 (Self-Signed Certificate)일 경우는 “SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER"선언된 코드를
    주석해제 하시면 됩니다. 물론 바로 위의 ” SSLSocketFactory.STRICT_HOSTNAME_VERIFIER"코드는 주석 처리
    하셔야 겠죠.^^ 실행을 하면 아래와 같이 Output를 확인 할수 있습니다.