![](/img/trans.png)
[英]Consuming Java / Spring rest service using HTTPs(and certificate)
[英]Consuming RESTful service over https with certificate using Java
我是REST服務的新用戶。 我需要使用Jersey生成的RESTful API服務。 問題出現是因為該服務托管在遠程主機上,並且需要https訪問證書。
我從組織獲得了我的證書,並且我能夠使用我的任何瀏覽器訪問該REST API服務(其上設置了證書)。
我在這里閱讀了很多帖子,我已經按照這個主題的答案: 在Java中使用HTTPS和REST
現在我在我的Java Keystore上設置了證書。 但我不知道如何在我的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();
}
}
我讀到了使用系統集屬性來指定密鑰庫的路徑,使用以下代碼:
System.setProperty("javax.net.ssl.keyStore", "/path/to/keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
我仍然在連接到遠程服務器時遇到401錯誤。
但后來我不知道如何在密鑰庫上使用我的證書進行SSL連接。 我也一直在閱讀有關使用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);
}
}
好的,這是我寫的最后一個腳本。 我可以連接到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());
}
}
假設您正在服務器上部署此代碼並且您已正確完成所有其他操作(例如正確生成密鑰庫核心並將其放置在服務器可以訪問的位置,使用與您的代碼相同的Java版本來生成密鑰庫)那么我認為你需要做的是添加以下內容
<Connector SSLEnabled="true" clientAuth="false" keystoreFile="pathToKeystore" keystorePass="password" maxThreads="150" port="443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/>
在運行客戶端的Server實例的server.xml中
<Connector connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443"/>
IMP:如果您在此代碼旁邊使用Skype,請務必(取消選中)更改默認值,因為它還使用相同的端口(80和443)進行其他連接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.