SSL(TLS) Authentication:Web Services and Java
来源:互联网 发布:linux限制ip访问端口 编辑:程序博客网 时间:2024/04/30 00:05
In this article we will talk about the SSL(TLS) authentication implementation as required when say calling a web serivce or making an HTTP get call using Java. SSL authentication can be either one way or mutual - where both consumer and provider must authenticate themselves. Lets first start with consumer of a web service. For a web service consumer, there are two major entities that you will be working with The Service endpoint interface(port) and the Service class itself. Lets look at how you obtain the port
This method will return you the port of the service you are trying to consume when the address is provided
JaxWsProxyFactoryBean beanFactory = new JaxWsProxyFactoryBean();
beanFactory.setServiceClass(KtipServiceSoap.class);
beanFactory.setAddress("http://localhost:port/KtipService/xxxx");
return (KtipServiceSoap)beanFactory.create();
The SSL authenticaion parameters are passed in through the org.apache.cxf.transport.http.HTTPConduit. (Please note instead of passing SSL parameters through the configuration file, we are passing in through the code ). To get the conduit we must first get the org.apache.cxf.endpoint.Client fromthe port we just obtained. This is done as shown in Listing II.
KtipServiceSoap port = ...// obtained using the code from Listing I
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);
HTTPConduit conduit = (HTTPConduit)client.getConduit();
conduit.setTlsClientParameters(fillTLSParameters());
Now we will look at how we actually set the TLS parameters for the conduit. We can call a method that will populate the required parameters. The method will look as shown below in Listing III.
org.apache.cxf.configuration.jsse.TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
KeyStore keyStore;
// Add trust managers (to authenticate the service)
keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("jks file location")), new String("password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustMgr = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustMgr);
// Add key managers (to authenticate the client)
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")), new String("password").toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, new String("customerInfoSys").toCharArray());
KeyManager[] keyMgr = keyFactory.getKeyManagers();
tlsParams.setKeyManagers(keyMgr);
FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);
return tlsParams;
So when you build your consumer, you should be provided .jks and .pfx files (and passwords for each) for mutual authentication. If there is only one way authentication to be performed by the service only and not the client, this would be done as shown in Listing IV.
org.apache.cxf.configuration.jsse.TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
KeyStore keyStore;
// Add trust managers (to authenticate the client)
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")), new String("password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustMgr = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustMgr);
FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);
return tlsParams;
In this part I will show how to write a simple Java method to make a HTTP GET/POST when the caller has to be authenticated
String getHTMLData(String address) throws Exception{
String response = null;
URLConnection connection = new URL(address).openConnection();
HttpsURLConnection sslConnection = null;
HttpURLConnection nonsslConnection = null;
if(connection instanceof HttpsURLConnection){
sslConnection = (HttpsURLConnection)connection;
sslConnection.setSSLSocketFactory(createSocketFactory());
sslConnection.setRequestMethod("GET");
if(sslConnection.getResponseCode() == HttpsURLConnection.HTTP_INTERNAL_ERROR ){
throw new AdServerException("Problem calling ad server...");
}
}else if(connection instanceof HttpURLConnection){
nonsslConnection = (HttpURLConnection)connection;
nonsslConnection.setRequestMethod("GET");
}
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder data = new StringBuilder(150);
String line;
while ((line = rd.readLine()) != null) data.append(line);
rd.close();
response = data.toString();
if(connection instanceof HttpsURLConnection) sslConnection.disconnect();
else if(connection instanceof HttpURLConnection) nonsslConnection.disconnect();
return response;
}
To create the HTTPS connection with the right SSL parameters, you use the javax.net.ssl.SSLSocketFactory. As shown in listing VI
SSLSocketFactory createSocketFactory() throws Exception {
KeyStore keyStore;
// This is a one-way authentication
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")),
new String("pfx password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] tm = trustFactory.getTrustManagers();
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(null, tm, null);
SSLSocketFactory socketFactory = context.getSocketFactory();
return socketFactory;
}
This method will return you the port of the service you are trying to consume when the address is provided
JaxWsProxyFactoryBean beanFactory = new JaxWsProxyFactoryBean();
beanFactory.setServiceClass(KtipServiceSoap.class);
beanFactory.setAddress("http://localhost:port/KtipService/xxxx");
return (KtipServiceSoap)beanFactory.create();
Listing I
The SSL authenticaion parameters are passed in through the org.apache.cxf.transport.http.HTTPConduit. (Please note instead of passing SSL parameters through the configuration file, we are passing in through the code ). To get the conduit we must first get the org.apache.cxf.endpoint.Client fromthe port we just obtained. This is done as shown in Listing II.
KtipServiceSoap port = ...// obtained using the code from Listing I
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);
HTTPConduit conduit = (HTTPConduit)client.getConduit();
conduit.setTlsClientParameters(fillTLSParameters());
Listing II
Now we will look at how we actually set the TLS parameters for the conduit. We can call a method that will populate the required parameters. The method will look as shown below in Listing III.
org.apache.cxf.configuration.jsse.TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
KeyStore keyStore;
// Add trust managers (to authenticate the service)
keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("jks file location")), new String("password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustMgr = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustMgr);
// Add key managers (to authenticate the client)
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")), new String("password").toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, new String("customerInfoSys").toCharArray());
KeyManager[] keyMgr = keyFactory.getKeyManagers();
tlsParams.setKeyManagers(keyMgr);
FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);
return tlsParams;
Listing III
So when you build your consumer, you should be provided .jks and .pfx files (and passwords for each) for mutual authentication. If there is only one way authentication to be performed by the service only and not the client, this would be done as shown in Listing IV.
org.apache.cxf.configuration.jsse.TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
KeyStore keyStore;
// Add trust managers (to authenticate the client)
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")), new String("password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] trustMgr = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(trustMgr);
FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);
return tlsParams;
Listing IV
In this part I will show how to write a simple Java method to make a HTTP GET/POST when the caller has to be authenticated
String getHTMLData(String address) throws Exception{
String response = null;
URLConnection connection = new URL(address).openConnection();
HttpsURLConnection sslConnection = null;
HttpURLConnection nonsslConnection = null;
if(connection instanceof HttpsURLConnection){
sslConnection = (HttpsURLConnection)connection;
sslConnection.setSSLSocketFactory(createSocketFactory());
sslConnection.setRequestMethod("GET");
if(sslConnection.getResponseCode() == HttpsURLConnection.HTTP_INTERNAL_ERROR ){
throw new AdServerException("Problem calling ad server...");
}
}else if(connection instanceof HttpURLConnection){
nonsslConnection = (HttpURLConnection)connection;
nonsslConnection.setRequestMethod("GET");
}
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder data = new StringBuilder(150);
String line;
while ((line = rd.readLine()) != null) data.append(line);
rd.close();
response = data.toString();
if(connection instanceof HttpsURLConnection) sslConnection.disconnect();
else if(connection instanceof HttpURLConnection) nonsslConnection.disconnect();
return response;
}
Listing V
To create the HTTPS connection with the right SSL parameters, you use the javax.net.ssl.SSLSocketFactory. As shown in listing VI
SSLSocketFactory createSocketFactory() throws Exception {
KeyStore keyStore;
// This is a one-way authentication
keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File("pfx file location")),
new String("pfx password").toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] tm = trustFactory.getTrustManagers();
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(null, tm, null);
SSLSocketFactory socketFactory = context.getSocketFactory();
return socketFactory;
}
Listing VI
- SSL(TLS) Authentication:Web Services and Java
- TLS and SSL
- 【SSL/TLS】TLS Stack and HandShake detail
- TLS, SSL, and HTTPS 升级
- HTTPS/SSL/TLS/ web 服务器
- 读《Java Web Services: Up and Running》
- Java Web services and Apache Tomcat
- Consuming P6 Web Services over HTTPS (SSL) From Java
- Java安全之SSL/TLS
- Bulletproof SSL and TLS(读书笔记)
- SSL & TLS Essentials: Securing the Web
- Web Services and Workflow
- PHP and Web Services
- SSL/TLS
- SSL/TLS
- TLS SSL
- ssl/tls
- SSL/TLS
- emctl start dbconsole遇到错误:OC4J Configuration issue
- shell中很强大的cut命令
- 对方阵顺时针旋转
- 开发小技巧: 如何在jQuery中禁用或者启用滚动事件.scroll
- ICE Manual(Documentation for Ice 3.5)---Language Mappings
- SSL(TLS) Authentication:Web Services and Java
- jboss7 以modules方式部署第三方jar
- ubuntu 搭建smb
- windows phone:自定义按钮
- Eclipse 调试时打开变量的鼠标悬浮提示功能
- linux 开发 tips
- uc/GUI 汉字显示
- ZBlog2.1网站搬家总结
- OpenCV简介