1. 程式人生 > >Tomcat + 數字證書 部署webservice (客戶端呼叫https webService)

Tomcat + 數字證書 部署webservice (客戶端呼叫https webService)

關於tomcat +數字證書類例子網路上很多,使用keytool工具即可,配置可見:

webService打包部署tomcat:

需要jar包:jaxws-2_0.jar  可到官網下載

WebService目錄結構:


package com.huzhe.service;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

import com.huzhe.po.Student;

@WebService
public interface IStudentService {
	
	 @WebMethod
	 Student getStudentById(@WebParam(name="id")String id); 
}

package com.huzhe.service;

import java.util.ArrayList;
import java.util.List;

import javax.jws.WebService;

import com.huzhe.po.Student;

@WebService(endpointInterface="com.huzhe.service.IStudentService")
public class StudentImpl implements IStudentService {

	@Override
	public Student getStudentById(String id) {
		return  new Student(id, "張三");
	}
}

--------------------------------------------------------------------------------------------------------------------------------------

在執行下面之前,請確保webService可以正常訪問,下面的內容主要涉及到tomcat部署以及https呼叫

--------------------------------------------------------------------------------------------------------------------------------------

配置:cmd   進入 該專案  clesses 目錄下:執行:

wsgen -cp . com.xx.service.StudentImpl

在web.xml中加入:

<login-config>
        <auth-method>CLIENT-CERT</auth-method>
        <realm-name>Client Cert Users-only Area</realm-name>
    </login-config>
    <security-constraint>
          
        <web-resource-collection >
            <web-resource-name >SSL</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
</security-constraint>


<listener>  
        <listener-class>  
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener  
        </listener-class>  
    </listener>  
    <servlet>  
        <servlet-name>studentImpl</servlet-name>  
        <servlet-class>  
            com.sun.xml.ws.transport.http.servlet.WSServlet  
        </servlet-class>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>studentImpl</servlet-name>  
        <url-pattern>/studentImpl</url-pattern>  
</servlet-mapping>
在web-inf下建立:sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
	version="2.0">
	<endpoint name="StudentImplWS" implementation="com.huzhe.service.StudentImpl"
		url-pattern="/studentImpl" />
</endpoints>

然後打包:war 使用maven或者直接Eclipse匯出  war

得到:ws.war

放到:tomcat webapp下面啟動伺服器;

說明已經加密了

根據wsdl檔案使用eclipse生成webService客戶端

(wsdl檔案可以使用命令生成,最簡單的方法:訪問上邊的地址得到xml資訊  直接複製  儲存為 ws.wsdl檔案即可)

IStudentServiceProxy p = newIStudentServiceProxy();
p.getIStudentService().getStudentById("001")
                  .getName()


直接訪問:出錯   如下:

AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
 faultSubcode: 
 faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 faultActor: 
 faultNode: 
 faultDetail: 
	{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
	at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
	at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
	at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
	at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
	at org.apache.axis.transport.http.HTTPSender.readFromSocket(HTTPSender.java:727)
	at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:144)
	at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
	at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
	at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
	at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
	at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
	at org.apache.axis.client.Call.invoke(Call.java:2767)
	at org.apache.axis.client.Call.invoke(Call.java:2443)
	at org.apache.axis.client.Call.invoke(Call.java:2366)
	at org.apache.axis.client.Call.invoke(Call.java:1812)
	at com.huzhe.client.StudentImplServiceSoapBindingStub.getStudentById(StudentImplServiceSoapBindingStub.java:228)
	at com.huzhe.client.ClientTest.main(ClientTest.java:18)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
	at sun.security.validator.Validator.validate(Validator.java:218)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
	... 24 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
	... 30 more

	{http://xml.apache.org/axis/}hostname:ISS-03261128

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
	at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:154)
	at org.apache.axis.transport.http.HTTPSender.readFromSocket(HTTPSender.java:727)
	at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:144)
	at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
	at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
	at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
	at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
	at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
	at org.apache.axis.client.Call.invoke(Call.java:2767)
	at org.apache.axis.client.Call.invoke(Call.java:2443)
	at org.apache.axis.client.Call.invoke(Call.java:2366)
	at org.apache.axis.client.Call.invoke(Call.java:1812)
	at com.huzhe.client.StudentImplServiceSoapBindingStub.getStudentById(StudentImplServiceSoapBindingStub.java:228)
	at com.huzhe.client.ClientTest.main(ClientTest.java:18)

原因是,客戶端沒有加入數字證書

在呼叫方法前加入程式碼:


public static void main(String[] args) {
		
		try {
			IStudentServiceProxy p = new IStudentServiceProxy();
			System.setProperty("javax.net.ssl.keyStore",
					"D:\\mykeystore\\test.keystore");
			System.setProperty("javax.net.ssl.keyStorePassword", "mulepassword");
			System.setProperty("javax.net.ssl.trustStore",
					"D:\\mykeystore\\test.keystore");
			System.setProperty("javax.net.ssl.trustStorePassword",
					"mulepassword");

			System.out.println(p.getIStudentService().getStudentById("001")
					.getName());

		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

成功!
D:\\mykeystore\\test.keystore
和tomcat裡配置的8443埠的keystore檔案一樣