上面三章做了通过WSDL文件生成java code的WebService服务器端和客户端例子。下面我们来做通过WSS4J对WebService的加密。
1.下载wss4j.jar 还是自己用google去找来下载。
2.把wss4j.jar 放到VacSyncService_WSS4J工程的 /WebContent/WEB-INF/lib 下。 可能提VacSyncService_WSS4J工程有点晕,其实这个就是前面我们使用的VacSyncService工程改了一下名字而已。
3.这下开始配置WEB-INFO 下的 deploy.wsdd
<!-- Use this file to deploy some handlers/chains and services -->
<!-- Two ways to do this: -->
<!-- java org.apache.axis.client.AdminClient deploy.wsdd -->
<!-- after the axis server is running -->
<!-- or -->
<!-- java org.apache.axis.utils.Admin client|server deploy.wsdd -->
<!-- from the same directory that the Axis engine runs -->
<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<!-- Services from SyncNotifySPServiceService WSDL service -->
<service name="SyncNotifySP" provider="java:RPC" style="rpc" use="encoded">
<requestFlow>
<handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
<parameter name="passwordCallbackClass" value="PWCallback"/>
<parameter name="action" value="UsernameToken"/>
</handler>
</requestFlow>
<parameter name="wsdlTargetNamespace" value="http://soap.bossagent.vac.unicom.com"/>
<parameter name="wsdlServiceElement" value="SyncNotifySPServiceService"/>
<parameter name="schemaUnqualified" value="http://rsp.sync.soap.bossagent.vac.unicom.com,http://req.sync.soap.bossagent.vac.unicom.com"/>
<parameter name="wsdlServicePort" value="SyncNotifySP"/>
<parameter name="className" value="com.unicom.vac.bossagent.soap.SyncNotifySPSoapBindingSkeleton"/>
<parameter name="wsdlPortType" value="SyncNotifySPService"/>
<parameter name="typeMappingVersion" value="1.2"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
<typeMapping
xmlns:ns="http://rsp.sync.soap.bossagent.vac.unicom.com"
qname="ns:OrderRelationUpdateNotifyResponse"
type="java:com.unicom.vac.bossagent.soap.sync.rsp.OrderRelationUpdateNotifyResponse"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
<typeMapping
xmlns:ns="http://req.sync.soap.bossagent.vac.unicom.com"
qname="ns:OrderRelationUpdateNotifyRequest"
type="java:com.unicom.vac.bossagent.soap.sync.req.OrderRelationUpdateNotifyRequest"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
</service>
</deployment>
红色字体为加入部分。
4.我们来写加密的类
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class PWCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof WSPasswordCallback) {
WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
// set the password given a username
if ("user".equals(pc.getIdentifer())) {
pc.setPassword("pawd");
}
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}
这个就是服务器端加密类。可以看到用户明就是user,密码就是pawd,这里可以根据自己需要用加密机或算法类处理一下。
5.在MyEclipse里面启动Tomcat。打开cmd输入:
C:/apache-tomcat-6.0.32/webapps/VacSyncService_WSS4J/WEB-INF>java -Djava.ext.dir
s="D:/workspace/VacSyncService_WSS4J/WebContent/WEB-INF/lib" org.apache.axis.cli
ent.AdminClient -lhttp://localhost:8080/VacSyncService_WSS4J/services/AdminServi
ce deploy.wsdd
在 /apache-tomcat-6.0.32/webapps/VacSyncService_WSS4J/WEB-INF/ 下会生成server-config.wsdd
6.到目前服务器端加密的用户验证就写完了,我们先用之前的客户端类调用一下这个WebService服务会抛如下错误:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultSubcode:
faultString: WSHandler: cannot load password callback class: PWCallback; nested exception is:
java.lang.ClassNotFoundException: PWCallback; nested exception is:
org.apache.ws.security.WSSecurityException: WSHandler: cannot load password callback class: PWCallback; nested exception is:
java.lang.ClassNotFoundException: PWCallback
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:3ABF8BC3B347428
WSHandler: cannot load password callback class: PWCallback; nested exception is:
java.lang.ClassNotFoundException: PWCallback; nested exception is:
org.apache.ws.security.WSSecurityException: WSHandler: cannot load password callback class: PWCallback; nested exception is:
java.lang.ClassNotFoundException: PWCallback
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1774)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2930)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
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.unicom.vac.bossagent.soap.SyncNotifySPSoapBindingStub.orderRelationUpdateNotify(SyncNotifySPSoapBindingStub.java:160)
at com.unicom.vac.bossagent.soap.WebServiceClient.setRequest(WebServiceClient.java:41)
at com.unicom.vac.bossagent.soap.WebServiceClient.main(WebServiceClient.java:59)
接下来我们来写客户端验证代码。