发布使用SSL的Web Service Apache CXF实战

在使用Web Service的时候,在很多情况下会要求我们发布ssl的web service,此时如果web service是作为一个war包部署在tomcat之类的web容器中的时候,我们可以通过修改tomcat的配置来比较容易的部署发布成ssl的web service的,当对于独立运行的程序来书,此时发布web service是需要一些操作的,下面看看在CXF中怎样发布并调用SSL的Web Service。
1. 首先是一个pojo的实体类
  1. package com.googlecode.garbagecan.cxfstudy.ssl;  
  2.   
  3. public class User {  
  4.     private String id;  
  5.     private String name;  
  6.     private String password;  
  7.     public String getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(String id) {  
  11.         this.id = id;  
  12.     }  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.     public String getPassword() {  
  20.         return password;  
  21.     }  
  22.     public void setPassword(String password) {  
  23.         this.password = password;  
  24.     }  
  25. }  
2. 下面是Web Service的接口和实现类,这两个类和前面文章中介绍的没什么区别
  1. package com.googlecode.garbagecan.cxfstudy.ssl;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.jws.WebMethod;  
  6. import javax.jws.WebResult;  
  7. import javax.jws.WebService;  
  8.   
  9. @WebService  
  10. public interface UserService {  
  11.     @WebMethod  
  12.     @WebResult List<User> list();  
  13.   
  14. }  
  15.   
  16. package com.googlecode.garbagecan.cxfstudy.ssl;  
  17.   
  18. import java.util.ArrayList;  
  19. import java.util.List;  
  20.   
  21. public class UserServiceImpl implements UserService {  
  22.   
  23.     public List<User> list() {  
  24.         List<User> users = new ArrayList<User>();  
  25.         for (int i = 0; i < 10; i++) {  
  26.             User user = new User();  
  27.             user.setId("" + i);  
  28.             user.setName("user_" + i);  
  29.             user.setPassword("password_" + i);  
  30.             users.add(user);  
  31.         }  
  32.         return users;  
  33.     }  
  34.   
  35. }  
3. 下面看看Server端代码
  1. package com.googlecode.garbagecan.cxfstudy.ssl;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.security.KeyStore;  
  6.   
  7. import javax.net.ssl.KeyManager;  
  8. import javax.net.ssl.KeyManagerFactory;  
  9. import javax.net.ssl.TrustManager;  
  10. import javax.net.ssl.TrustManagerFactory;  
  11.   
  12. import org.apache.cxf.configuration.jsse.TLSServerParameters;  
  13. import org.apache.cxf.configuration.security.ClientAuthentication;  
  14. import org.apache.cxf.configuration.security.FiltersType;  
  15. import org.apache.cxf.endpoint.Server;  
  16. import org.apache.cxf.jaxws.JaxWsServerFactoryBean;  
  17. import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory;  
  18.   
  19. public class MyServer {  
  20.   
  21.     private static final int port = 12345;  
  22.       
  23.     private static final String address = "https://0.0.0.0:"+port+"/ws/ssl/userService";  
  24.   
  25.     public static void main(String[] args) throws Exception {  
  26.         System.out.println("Starting Server");  
  27.           
  28.         configureSSLOnTheServer();  
  29.           
  30.         JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();  
  31.         factoryBean.setServiceClass(UserServiceImpl.class);  
  32.         factoryBean.setAddress(address);  
  33.           
  34.         Server server = factoryBean.create();  
  35.         String endpoint = server.getEndpoint().getEndpointInfo().getAddress();  
  36.   
  37.         System.out.println("Server started at " + endpoint);  
  38.     }  
  39.   
  40.     public static void configureSSLOnTheServer() {  
  41.         File file = new File(MyServer.class.getResource("/com/googlecode/garbagecan/cxfstudy/ssl/test.jks").getFile());  
  42.           
  43.         try {  
  44.             TLSServerParameters tlsParams = new TLSServerParameters();  
  45.             KeyStore keyStore = KeyStore.getInstance("JKS");  
  46.             String password = "mypassword";  
  47.             String storePassword = "mypassword";  
  48.               
  49.             keyStore.load(new FileInputStream(file), storePassword.toCharArray());  
  50.             KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
  51.             keyFactory.init(keyStore, password.toCharArray());  
  52.             KeyManager[] keyManagers = keyFactory.getKeyManagers();  
  53.             tlsParams.setKeyManagers(keyManagers);  
  54.   
  55.             keyStore.load(new FileInputStream(file), storePassword.toCharArray());  
  56.             TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  
  57.             trustFactory.init(keyStore);  
  58.             TrustManager[] trustManagers = trustFactory.getTrustManagers();  
  59.             tlsParams.setTrustManagers(trustManagers);  
  60.               
  61.             FiltersType filtersTypes = new FiltersType();  
  62.             filtersTypes.getInclude().add(".*_EXPORT_.*");  
  63.             filtersTypes.getInclude().add(".*_EXPORT1024_.*");  
  64.             filtersTypes.getInclude().add(".*_WITH_DES_.*");  
  65.             filtersTypes.getInclude().add(".*_WITH_NULL_.*");  
  66.             filtersTypes.getExclude().add(".*_DH_anon_.*");  
  67.             tlsParams.setCipherSuitesFilter(filtersTypes);  
  68.               
  69.             ClientAuthentication ca = new ClientAuthentication();  
  70.             ca.setRequired(true);  
  71.             ca.setWant(true);  
  72.             tlsParams.setClientAuthentication(ca);  
  73.               
  74.             JettyHTTPServerEngineFactory factory = new JettyHTTPServerEngineFactory();  
  75.             factory.setTLSServerParametersForPort(port, tlsParams);  
  76.         } catch (Exception e) {  
  77.             e.printStackTrace();  
  78.         }  
  79.     }  
  80.   
  81. }  
4. 下面看看Client端代码
  1. package com.googlecode.garbagecan.cxfstudy.ssl;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.security.KeyStore;  
  6.   
  7. import javax.net.ssl.KeyManager;  
  8. import javax.net.ssl.KeyManagerFactory;  
  9. import javax.net.ssl.TrustManager;  
  10. import javax.net.ssl.TrustManagerFactory;  
  11.   
  12. import org.apache.cxf.configuration.jsse.TLSClientParameters;  
  13. import org.apache.cxf.configuration.security.FiltersType;  
  14. import org.apache.cxf.endpoint.Client;  
  15. import org.apache.cxf.frontend.ClientProxy;  
  16. import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  17. import org.apache.cxf.transport.http.HTTPConduit;  
  18.   
  19. public class MyClient {  
  20.   
  21.     private static final String address = "https://localhost:12345/ws/ssl/userService";  
  22.   
  23.     public static void main(String[] args) throws Exception {  
  24.         JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();  
  25.         factoryBean.setAddress(address);  
  26.         factoryBean.setServiceClass(UserService.class);  
  27.         Object obj = factoryBean.create();  
  28.         UserService userService = (UserService) obj;  
  29.           
  30.         configureSSLOnTheClient(userService);  
  31.   
  32.         System.out.println(userService.list());  
  33.     }  
  34.   
  35.     private static void configureSSLOnTheClient(Object obj) {  
  36.         File file = new File(MyServer.class.getResource("/com/googlecode/garbagecan/cxfstudy/ssl/test.jks").getFile());  
  37.           
  38.         Client client = ClientProxy.getClient(obj);  
  39.         HTTPConduit httpConduit = (HTTPConduit) client.getConduit();  
  40.   
  41.         try {  
  42.             TLSClientParameters tlsParams = new TLSClientParameters();  
  43.             tlsParams.setDisableCNCheck(true);  
  44.   
  45.             KeyStore keyStore = KeyStore.getInstance("JKS");  
  46.             String password = "mypassword";  
  47.             String storePassword = "mypassword";  
  48.               
  49.             keyStore.load(new FileInputStream(file), storePassword.toCharArray());  
  50.             TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  
  51.             trustFactory.init(keyStore);  
  52.             TrustManager[] trustManagers = trustFactory.getTrustManagers();  
  53.             tlsParams.setTrustManagers(trustManagers);  
  54.   
  55.             keyStore.load(new FileInputStream(file), storePassword.toCharArray());  
  56.             KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
  57.             keyFactory.init(keyStore, password.toCharArray());  
  58.             KeyManager[] keyManagers = keyFactory.getKeyManagers();  
  59.             tlsParams.setKeyManagers(keyManagers);  
  60.               
  61.             FiltersType filtersTypes = new FiltersType();  
  62.             filtersTypes.getInclude().add(".*_EXPORT_.*");  
  63.             filtersTypes.getInclude().add(".*_EXPORT1024_.*");  
  64.             filtersTypes.getInclude().add(".*_WITH_DES_.*");  
  65.             filtersTypes.getInclude().add(".*_WITH_NULL_.*");  
  66.             filtersTypes.getExclude().add(".*_DH_anon_.*");  
  67.             tlsParams.setCipherSuitesFilter(filtersTypes);  
  68.   
  69.             httpConduit.setTlsClientParameters(tlsParams);  
  70.         } catch (Exception e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.     }  
  74. }  
5. 我们需要手动生成jks文件,并将其放在maven工程resources的/com/googlecode/garbagecan/cxfstudy/ssl/目录下,下面是手动生成时使用的命令
  1. keytool -genkey -alias test -keyalg RSA -keypass mypassword -storepass mypassword -dname "CN=, OU=, O=, L=, ST=, C=" -validity 3650 -keystore test.jks  
6. 最后我们可以通过启动MyServer和MyClient来验证我们的测试。


实际项目:
otpServer 伊朗samen银行WebServicet增加SSL支持:

服务端:
/**
* SSL设置
* @author accompany
*/
private void configureSSLOnTheServer() {
// String keystorePath = Constant.ROOT_PATH + Constant.SAMEN_CER; // keystore路径,jks文件路径
String keystorePath = Constant.ROOT_PATH + "/conf/otpserver.jks"; // keystore路径,jks文件路径
File file = new File(keystorePath);
try {
TLSServerParameters tlsParams = new TLSServerParameters();
KeyStore keyStore = KeyStore.getInstance("JKS");

// String keypass = (String) ServConfConfig.getValue(Constant.WEBSERVICE_PASSWORD); // 密钥对密码
String keypass = "otpserver"; // 密钥对密码

// String storepass = (String) ServConfConfig.getValue(Constant.WEBSERVICE_PASSWORD); // 密钥库密码
String storepass = "otpserver"; // 密钥库密码

// 服务器证书库
keyStore.load(new FileInputStream(file), storepass.toCharArray());
//加载的keystore和server密钥对的密码(keypass)来初始化
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, keypass.toCharArray());
KeyManager[] keyManagers = keyFactory.getKeyManagers();
tlsParams.setKeyManagers(keyManagers);

ClientAuthentication ca = new ClientAuthentication();
ca.setRequired(false);
ca.setWant(false); //单向认证,客户端验证服务器,服务器不验证客户端
tlsParams.setClientAuthentication(ca);

JettyHTTPServerEngineFactory factory = new JettyHTTPServerEngineFactory();
factory.destroyForPort(soapPort);
factory.setTLSServerParametersForPort(soapPort, tlsParams);
} catch (Exception e) {
e.printStackTrace();
logger.error("configure SSL to webservice error:" + e.getMessage());
}
}

客户端:

在WebserviceFactory中的构造中添加:
System.setPropertory("javax.net.ssl.trustStore","A:/jdk/bin/otpserver.jks");
添加信任证书



用jdk/bin/keyTool.exe文件生成jks证书命令:
keytool -genkey -alias yilang -keysize 2048 -validity 3650 -keyalg RSA -dname "CN=192.168.16.128" -keypass otpserver -storepass otpserver -keystore otpserver.jks

keytool -list -v -keystore samen.jks -storepass otpserver
或者
keytool -list -v -keystore otpserver.jks

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值