本次调研主要为了解决两个问题: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实现负载均衡。