本次調研主要爲了解決兩個問題:java
但願達到的目標網絡模型以下:nginx
經過對SSL的學習,結合自身業務的考慮,對SSL的使用作以下說明:git
我這裏SSL使用TLSv1,而且服務端不須要校驗客戶端的身份合法性,則使用SSL單向認證方式,只須要服務端證書。另外咱們只須要用到SSL的鏈路加密,因此能夠設置客戶端對服務端證書保持永久信任web
這裏restful使用jersey來實現,使用jetty做爲javaee容器。windows
經過jetty發佈非加密restful服務,url爲 http://localhost:8080/api/v1/....api
web.xmlrestful
<servlet> <servlet-name>RestApplication</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.spiro.test.jersey.MyApplication</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>RestApplication</servlet-name> <url-pattern>/api/v1/*</url-pattern> </servlet-mapping>
Resource:網絡
import com.spiro.test.jersey.entity.Terminal; import javax.inject.Singleton; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.ArrayList; import java.util.List; @Path("terminals") @Singleton public class TerminalsResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response getAll() { List<Terminal> terminals = new ArrayList<Terminal>(); Terminal ter1 = new Terminal(); ter1.setId("101"); ter1.setDesc("I'm 101"); terminals.add(ter1); Terminal ter2 = new Terminal(); ter2.setId("102"); ter2.setDesc("I'm 102"); terminals.add(ter2); // if(true) { // return Response.status(Response.Status.UNAUTHORIZED).build(); // } return Response.ok(terminals).build(); } }
ResourceConfig:session
import com.spiro.test.jersey.resources.TerminalsResource; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; public class MyApplication extends ResourceConfig { public MyApplication() { register(TerminalsResource.class); register(JacksonFeature.class); } }
public static void testHttp() { ClientConfig clientConfig = new ClientConfig(); Client client = ClientBuilder.newClient(clientConfig); String url = "http://localhost:8080/api/v1/"; String entity = client.target(url) .path("terminals") .request(MediaType.APPLICATION_JSON) .get(String.class); System.out.println(entity); }
經測試成功打印:[{"id":"101","desc":"I'm 101"},{"id":"102","desc":"I'm 102"}]app
在windows7機器上安裝nginx-1.10.1,配置以下:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; server { listen 443 ssl; server_name localhost; ssl_certificate D:/server.crt; ssl_certificate_key D:/_server.key; location / { proxy_pass http://127.0.0.1:8080; } } }
同2.1.1
// Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; // Install the all-trusting trust manager SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); // Create all-trusting host name verifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); Client client = ClientBuilder.newBuilder().sslContext(sslContext).build(); String entity = client.target("https://127.0.0.1:443/api/v1/") .path("terminals") .request(MediaType.APPLICATION_JSON) .get(String.class); System.out.println(entity);
設置客戶端請求鏈接爲ssl加密,而且客戶端永久信任服務端,不對服務端證書進行驗證。
經測試成功打印:[{"id":"101","desc":"I'm 101"},{"id":"102","desc":"I'm 102"}]
經測試,能夠經過nginx https代理restful 實現鏈路加密,後續可經過nginx upstream實現負載均衡。