2012-07-11 3 views
10

저는 REST 서비스에 대한 새로운 사용자입니다. 저지와 함께 생성 된 RESTful API 서비스를 사용해야합니다. 이 문제는 원격 호스트에서 서비스가 호스팅되고 인증서가있는 https 액세스가 필요하기 때문에 발생합니다.Java를 사용하는 certficate로 https를 통한 RESTful 서비스 사용

조직에서 내 인증서를 받았는데 인증서가있는 브라우저를 사용하여 REST API 서비스에 액세스 할 수 있습니다.

내가 여기에 글을 많이 읽었습니다, 나는이 주제에 대한 답을 따랐습니다 : Using HTTPS with REST in Java

지금 내 자바 키 저장소에 내 인증서 설치를했습니다. 하지만 내 Java 프로그램에서 https 연결을 수행하는 데 필요한 인증서를 정확하게 사용하는 방법을 사용하는 방법을 모르겠습니다.

이것은 로컬 테스트를위한 간단한 연결 코드입니다.

package rest.test.first; 
import java.net.URI; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.UriBuilder; 

import com.sun.jersey.api.client.Client; 
import com.sun.jersey.api.client.ClientResponse; 
import com.sun.jersey.api.client.WebResource; 
import com.sun.jersey.api.client.config.ClientConfig; 
import com.sun.jersey.api.client.config.DefaultClientConfig; 

public class TestClient{ 
public static void main(String[]args){ 
    ClientConfig config= new DefaultClientConfig(); 
    Client client=Client.create(config); 
    WebResource service=client.resource(getBaseURI()); 
    //Fluentinterfaces 
    System.out.println(service.path("rest").path("hello").accept(MediaType.TEXT_PLAIN).get(ClientResponse.class).toString()); 
    //Getplaintext 
    System.out.println(service.path("rest").path("hello").accept(MediaType.TEXT_PLAIN).get(String.class)); 
    //GetXML 
    System.out.println(service.path("rest").path("hello").accept(MediaType.TEXT_XML).get(String.class)); 
    //TheHTML 
    System.out.println(service.path("rest").path("hello").accept(MediaType.TEXT_HTML).get(String.class)); 
} 

private static URI getBaseURI(){ 
    return UriBuilder.fromUri("http://localhost:8080/rest.test").build(); 
} 
} 

은 I'v이 코드와 함께 키 스토어 경로를 지정하는 시스템 속성 설정을 사용하는 방법에 대한 읽기 :

System.setProperty("javax.net.ssl.keyStore", "/path/to/keystore.jks"); 
System.setProperty("javax.net.ssl.keyStorePassword", "password"); 

난 여전히 원격 서버에 연결 401 오류가 발생합니다.

그러나 그렇다면 키 저장소에서 인증서를 사용하여 SSL 연결을 만드는 방법을 모르겠습니다. 난 그냥 지금 ... How can I use different certificates on specific connections?

이 코드와 함께 키 스토어에서 내 인증서를 검색하기 위해 관리했습니다 : 을 나는 또한 이러한 목적의 SSLSocketFactory를 사용하는 방법에 대해 읽어 봤는데하지만,이 게시물에 설명 된대로 내가이 일을 만들 수 없습니다 연결하여 사용하는 방법을 알아야합니다.

package rest.test.first; 

    import java.io.FileInputStream; 
    import java.security.KeyStore; 
    import java.security.cert.Certificate; 

    public class keystore { 

     public static void main(String[] args) throws Exception { 
     String keystoreFilename = "/usr/lib/jvm/jdk1.6.0_32/jre/lib/security/cacerts"; 

     char[] password = "changeit".toCharArray(); 
     String alias = "remote_https_server"; 

     FileInputStream fIn = new FileInputStream(keystoreFilename); 
     KeyStore keystore = KeyStore.getInstance("JKS"); 

     keystore.load(fIn, password); 

     Certificate cert = keystore.getCertificate(alias); 

     System.out.println(cert); 
     } 
    } 

Ok. 이것이 제가 작성한 마지막 스크립트입니다. https 사이트에 연결할 수는 있지만 인증을 위해 인증서를 보내야하는 https 사이트에는 계속 연결할 수 없습니다.

package rest.test.first; 


import java.io.*; 
import java.net.*; 
import java.security.*; 

import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocketFactory; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.TrustManagerFactory; 


public class urlConnection{ 
    public static void main(String args[]) throws Exception { 

    System.setProperty("javax.net.ssl.trustStore", "/usr/lib/jvm/jdk1.6.0_32/jre/lib/security/cacerts"); 
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); 

     //TrustStore.. 
     char[] passphrase = "changeit".toCharArray(); //password 
     KeyStore keystore = KeyStore.getInstance("JKS"); 
     //KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keystore.load(new FileInputStream("/usr/lib/jvm/jdk1.6.0_32/jre/lib/security/cacerts"), passphrase); //path 

     //TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); //instance 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     tmf.init(keystore); 


     SSLContext context = SSLContext.getInstance("TLS"); 
     TrustManager[] trustManagers = tmf.getTrustManagers(); 
     context.init(null, trustManagers, null); 
     SSLSocketFactory sf = context.getSocketFactory(); 
     URL url = new URL("https://www.google.es"); 

     HttpsURLConnection httpsCon = (HttpsURLConnection) url.openConnection(); 
     httpsCon.setSSLSocketFactory(sf); 
     httpsCon.setRequestMethod("GET"); 

     /*InputStream inStrm = httpsCon.getInputStream(); 
     System.out.println("\nContent at " + url); 
     int ch; 
     while (((ch = inStrm.read()) != -1)){ 
      System.out.print((char) ch); 
     inStrm.close(); 
     }*/ 

     System.out.println("Response Message is " + httpsCon.getResponseMessage()); 

} 
} 
+1

키 저장소를 어떻게 생성 했습니까? 게시 한 코드에서 왜'cacerts' 트러스트 스토어를 사용하고 있습니까? 자체 JKS에 인증서를 가져 와서'System.setProperty ("javax.net.ssl.keyStore", "...") 호출에 사용하는 것이 좋습니다. – poida

답변

2

당신이 서버에이 코드를 배포하고 같이 같은 자바 버전을 사용하여 올바르게 스토어 코어를 생성하고이 서버에 액세스 할 수있는 위치에 그것을 배치처럼 (다른 정확하게 모든 일을했다고 가정 코드는 당신이 클라이언트와

<Connector connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443"/> 
를 실행하는 당신이 당신의 서버 인스턴스의 server.xml의

<Connector SSLEnabled="true" clientAuth="false" keystoreFile="pathToKeystore" keystorePass="password" maxThreads="150" port="443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/> 

다음을 추가한다 무엇을해야하는지 생각) 키 스토어를 생성하는

IMP :이 코드와 함께 Skype를 사용하는 경우 추가 연결에 동일한 포트 (80 및 443)를 사용하므로 기본값을 변경 (선택 취소)하십시오.