Jersey框架三:Jersey对HTTPS的支持
2016-12-06 17:46
363 查看
Jersey系列文章:
Jersey框架一:Jersey RESTful WebService框架简介
Jersey框架二:Jersey对JSON的支持
Jersey框架三:Jersey对HTTPS的支持
证书的生成过程这里就不介绍了,请参照:Java网络编程二:Java Secure(SSL/TLS) Socket实现 中的证书部分
代码结构如下:
Maven配置文件:
Person类是基本的JAXB:
客户端代码:
SSL握手过程中,会对请求IP或请求域名进行校验,如果在证书信息中无法找到相关请求IP或请求域名则会报错(javax.NET.ssl.SSLHandshakeException: Java.security.cert.CertificateException: No subject alternative names present)
这里实现自己的校验逻辑(如果请求的IP为127.0.0.1或请求的域名为localhost,则直接通过校验)以覆盖默认逻辑
服务端代码:
配置文件类:
配置文件config.properties:
服务端运行结果:
客户端运行结果
Jersey框架一:Jersey RESTful WebService框架简介
Jersey框架二:Jersey对JSON的支持
Jersey框架三:Jersey对HTTPS的支持
证书的生成过程这里就不介绍了,请参照:Java网络编程二:Java Secure(SSL/TLS) Socket实现 中的证书部分
代码结构如下:
Maven配置文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>JERSEY</groupId> <artifactId>JERSEY</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.18</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-grizzly2</artifactId> <version>1.18</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.18</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.15</version> </dependency> </dependencies> </project>
Person类是基本的JAXB:
package com.sean; import java.util.List; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Person { private String name; private List<String> addresses; public Person(){} public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getAddresses() { return addresses; } public void setAddresses(List<String> addresses) { this.addresses = addresses; } }
客户端代码:
package com.sean; import java.net.URI; import javax.net.ssl.SSLContext; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import org.glassfish.jersey.SslConfigurator; 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; import com.sun.jersey.client.urlconnection.HTTPSProperties; public class SSLClient { public static void main(String[] args) { int authType = Integer.valueOf(Config.getConfig().getProperty("authority")).intValue(); SslConfigurator sslConfig = SslConfigurator.newInstance(); if(authType == 1){ sslConfig.trustStoreFile(Config.getConfig().getProperty("clientTrustCer")) .trustStorePassword(Config.getConfig().getProperty("clientTrustCerPwd")); }else if(authType == 2){ sslConfig.keyStoreFile(Config.getConfig().getProperty("clientCer")) .keyStorePassword(Config.getConfig().getProperty("clientCerPwd")) .keyPassword(Config.getConfig().getProperty("clientKeyPwd")) .trustStoreFile(Config.getConfig().getProperty("clientTrustCer")) .trustStorePassword(Config.getConfig().getProperty("clientTrustCerPwd")); } sslConfig.securityProtocol(Config.getConfig().getProperty("protocol")); SSLContext sslContext = sslConfig.createSSLContext(); ClientConfig cc = new DefaultClientConfig(); cc.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(new MyHostnameVerifier(), sslContext)); Client client = Client.create(cc); URI uri = UriBuilder.fromUri("https://127.0.0.1/queryAddress").port(10000).build(); WebResource resource = client.resource(uri); Person person = new Person(); person.setName("sean"); ClientResponse response = resource .accept(MediaType.APPLICATION_XML) .type(MediaType.APPLICATION_XML) .post(ClientResponse.class, person); String addresses = response.getEntity(String.class); System.out.println(addresses); } }
SSL握手过程中,会对请求IP或请求域名进行校验,如果在证书信息中无法找到相关请求IP或请求域名则会报错(javax.NET.ssl.SSLHandshakeException: Java.security.cert.CertificateException: No subject alternative names present)
这里实现自己的校验逻辑(如果请求的IP为127.0.0.1或请求的域名为localhost,则直接通过校验)以覆盖默认逻辑
package com.sean; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; public class MyHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { if("127.0.0.1".equals(hostname) || "localhost".equals(hostname) ) return true; else return false; } }
服务端代码:
package com.sean; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import javax.net.ssl.SSLContext; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import org.glassfish.grizzly.http.server.HttpHandler; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.ssl.SSLEngineConfigurator; import org.glassfish.jersey.SslConfigurator; import com.sun.jersey.api.container.ContainerFactory; import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; @Path("queryAddress") public class SSLServer { @POST @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_XML) public Person queryAddress(String name) { System.out.println(name); Person person = new Person(); List<String> addresses = new ArrayList<String>(); addresses.add("address1"); addresses.add("address2"); person.setAddresses(addresses); return person; } public static void main(String[] args) { Integer authType = Integer.valueOf(Config.getConfig().getProperty("authority")).intValue(); SslConfigurator sslConfig = SslConfigurator.newInstance(); if(authType == 1){ sslConfig.keyStoreFile(Config.getConfig().getProperty("serverCer")) .keyStorePassword(Config.getConfig().getProperty("serverCerPwd")) .keyPassword(Config.getConfig().getProperty("serverKeyPwd")); }else if(authType == 2){ sslConfig.keyStoreFile(Config.getConfig().getProperty("serverCer")) .keyStorePassword(Config.getConfig().getProperty("serverCerPwd")) .keyPassword(Config.getConfig().getProperty("serverKeyPwd")) .trustStoreFile(Config.getConfig().getProperty("serverTrustCer")) .trustStorePassword(Config.getConfig().getProperty("serverTrustCerPwd")); } sslConfig.securityProtocol(Config.getConfig().getProperty("protocol")); SSLContext sslContext = sslConfig.createSSLContext(); SSLEngineConfigurator sslEngineConfig = new SSLEngineConfigurator(sslContext); //默认情况下是客户端模式,如果忘记修改模式 //会抛出异常 //javax.net.ssl.SSLProtocolException: Handshake message sequence violation, 1] sslEngineConfig.setClientMode(false); if(authType == 1) sslEngineConfig.setWantClientAuth(true); else if(authType == 2) sslEngineConfig.setNeedClientAuth(true); ResourceConfig rc = new PackagesResourceConfig("com.sean"); HttpHandler handler = ContainerFactory.createContainer( HttpHandler.class, rc); URI uri = UriBuilder.fromUri("https://127.0.0.1/").port(10000).build(); try { HttpServer server = GrizzlyServerFactory.createHttpServer(uri, handler, true, sslEngineConfig); server.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(1000*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
配置文件类:
package com.sean; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; public class Config{ private static Properties config; public static Properties getConfig(){ try{ if(null == config){ File configFile = new File("src/main/resources/config/config.properties"); if(configFile.exists() && configFile.isFile() && configFile.canRead()){ InputStream input = new FileInputStream(configFile); config = new Properties(); config.load(input); } } }catch(Exception e){ //default set config = new Properties(); config.setProperty("authority", String.valueOf(1)); config.setProperty("protocol", "SSL"); config.setProperty("serverCer", "src/main/resources/certificate/server.jks"); config.setProperty("serverCerPwd", "1234sp"); config.setProperty("serverKeyPwd", "1234kp"); config.setProperty("serverTrustCer", "src/main/resources/certificate/serverTrust.jks"); config.setProperty("serverTrustCerPwd", "1234sp"); config.setProperty("clientCer", "src/main/resources/certificate/client.jks"); config.setProperty("clientCerPwd", "1234sp"); config.setProperty("clientKeyPwd", "1234kp"); config.setProperty("clientTrustCer", "src/main/resources/certificate/clientTrust.jks"); config.setProperty("clientTrustCerPwd", "1234sp"); } return config; } }
配置文件config.properties:
#1:单向认证,只有服务器端需证明其身份 #2:双向认证,服务器端和客户端都需证明其身份 authority=2 #通信协议 protocol=SSL #服务端证书信息 serverCer=src/main/resources/certificate/server.jks #keystore的storepass serverCerPwd=1234sp #keystore的keypass serverKeyPwd=1234kp #服务端证书信息 serverTrustCer=src/main/resources/certificate/serverTrust.jks serverTrustCerPwd=1234sp #客户端证书信息 clientCer=src/main/resources/certificate/client.jks clientCerPwd=1234sp clientKeyPwd=1234kp clientTrustCer=src/main/resources/certificate/clientTrust.jks clientTrustCerPwd=1234sp
服务端运行结果:
三月 03, 2015 3:30:54 下午 com.sun.jersey.api.core.PackagesResourceConfig init INFO: Scanning for root resource and provider classes in the packages: com.sean 三月 03, 2015 3:30:54 下午 com.sun.jersey.api.core.ScanningResourceConfig logClasses INFO: Root resource classes found: class com.sean.SSLServer 三月 03, 2015 3:30:54 下午 com.sun.jersey.api.core.ScanningResourceConfig init INFO: No provider classes found. 三月 03, 2015 3:30:54 下午 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate INFO: Initiating Jersey application, version 'Jersey: 1.18 11/22/2013 01:21 AM' 三月 03, 2015 3:30:55 下午 org.glassfish.grizzly.http.server.NetworkListener start INFO: Started listener bound to [127.0.0.1:10000] 三月 03, 2015 3:30:55 下午 org.glassfish.grizzly.http.server.HttpServer start INFO: [HttpServer] Started. <?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><name>sean</name></person>
客户端运行结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><addresses>address1</addresses><addresses>address2</addresses></person>
相关文章推荐
- The method getContextPath() from the type HttpServletRequest refers to the missing type
- android----AsyncHttpClient的get,post和图片上传
- socket通信中select函数的使用和解释
- 随机梯度下降
- iOS获取当前网络环境
- CXF如何获取Http对象
- 2017年深圳普飞全国巡回数字网传器/网络楼层显示器专展
- 20145310《信息安全系统设计基础》实验五 网络通信
- HTTP/1.1协议中共定义了八种方法
- TCPIP协议详解----TCP/IP基础知识
- Https单向认证和双向认证
- TCP拥塞控制
- JMeter学习-012-JMeter 配置元件之-HTTP Cookie管理器-实现 Cookie 登录
- UNIX网络编程(五)getsockname和getpeername
- Android 注册广播,实时监听网络连接与断开状态变化
- Android学习笔记(十八):ImageView设置网络图片
- FastCGI进程意外退出,http错误404.3-NotFound 由于扩展配置问题 dll找不到找定的模块等 dz问题总结
- TCPIP协议详解----网络基础知识
- 使用OpenVSwitch、netns构建复杂的虚拟网络
- Android中如何根据图片url路径来获取网络图片