zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Jersey框架三:Jersey对HTTPS的支持详解编程语言

框架HTTPS编程语言 详解 支持 jersey
2023-06-13 09:11:51 时间

Jersey系列文章:

Jersey框架一:Jersey RESTful WebService框架简介

Jersey框架二:Jersey对JSON的支持

Jersey框架三:Jersey对HTTPS的支持

证书的生成过程这里就不介绍了,请参照:Java网络编程二:Java Secure(SSL/TLS) Socket实现 中的证书部分

代码结构如下:

Jersey框架三:Jersey对HTTPS的支持详解编程语言

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 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/19463.html

cjavaxml