2013-08-19 45 views
0

我使用wssec_sign_enc示例在Apache Tomcat 7.0.29下部署的apacheCxf jar中的ws安全示例中。 我的web.xml是:如何連接到Apache Tomcat上啓動的Apache Cxf Web服務(啓用了Ws安全性)?

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 
    <display-name>TestingWebWsSecurity</display-name> 
    <welcome-file-list> 
    <welcome-file>index.html</welcome-file> 

    </welcome-file-list> 
    <servlet> 
    <description>Apache CXF Endpoint</description> 
    <display-name>cxf</display-name> 
    <servlet-name>cxf</servlet-name> 
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>cxf</servlet-name> 
    <url-pattern>/services/*</url-pattern> 
    </servlet-mapping> 
    <session-config> 
    <session-timeout>60</session-timeout> 
    </session-config> 
    <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>WEB-INF/cxf-beans.xml</param-value> 
    </context-param> 
    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    </web-app> 

我CXF-beans.xml文件是

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" 
    xmlns:cxf="http://cxf.apache.org/core" xmlns:wsa="http://cxf.apache.org/ws/addressing" 
    xmlns:http="http://cxf.apache.org/transports/http/configuration" 
    xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy" 
    xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager" 
    xsi:schemaLocation="  http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd  http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd  http://schemas.xmlsoap.org/ws/2005/02/rm/policy http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd  http://cxf.apache.org/ws/rm/manager http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  http://cxf.apache.org/jaxws  http://cxf.apache.org/schemas/jaxws.xsd "> 
    <import resource="classpath:META-INF/cxf/cxf.xml" /> 
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> 
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> 
    <import resource="classpath:META-INF/cxf/cxf.xml" /> 
    <import resource="classpath*:META-INF/cxf/cxf-extension-*.xml" /> 


    <cxf:bus> 
     <cxf:features> 
      <cxf:logging /> 
      <wsa:addressing /> 
     </cxf:features> 
    </cxf:bus> 

    <http:conduit 
     name="{http://cxf.apache.org/hello_world_soap_http}GreeterPort.http-conduit"> 
     <http:client DecoupledEndpoint="http://localhost:12000/decoupled_endpoint" /> 
    </http:conduit> 

    <jaxws:endpoint xmlns:tns="http://cxf.apache.org/hello_world_soap_http" 
     id="greeter" implementor="org.apache.cxf.hello_world_soap_http.GreeterImpl" 
     wsdlLocation="wsdl/hello_world_wssec.wsdl" endpointName="tns:GreeterPort" 
     serviceName="tns:GreeterService" address="/GreeterPort"> 
     <jaxws:features> 
      <bean class="org.apache.cxf.feature.LoggingFeature" /> 
     </jaxws:features> 
     <jaxws:outInterceptors> 
      <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> 
       <constructor-arg> 
        <map> 
         <entry key="action" value="UsernameToken Timestamp Signature Encrypt" /> 
         <entry key="passwordType" value="PasswordText" /> 
         <entry key="passwordCallbackClass" value="demo.wssec.server.UTPasswordCallback" /> 
         <entry key="user" value="Alice" /> 
         <entry key="signatureUser" value="serverx509v1" /> 
         <entry key="encryptionUser" value="clientx509v1" /> 
         <entry key="encryptionPropFile" value="etc/Server_SignVerf.properties" /> 
         <entry key="encryptionKeyIdentifier" value="IssuerSerial" /> 
         <entry key="encryptionParts" 
          value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body" /> 
         <entry key="signaturePropFile" value="etc/Server_Decrypt.properties" /> 
         <entry key="signatureParts" 
          value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body" /> 
         <entry key="signatureKeyIdentifier" value="DirectReference" /> 

         <entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" /> 
         <entry key="signatureAlgorithm" value="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> 
        </map> 
       </constructor-arg> 
      </bean> 
     </jaxws:outInterceptors> 
     <jaxws:inInterceptors> 
      <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> 
       <constructor-arg> 
        <map> 
         <entry key="action" value="UsernameToken Timestamp Signature Encrypt" /> 
         <entry key="passwordType" value="PasswordDigest" /> 
         <entry key="passwordCallbackClass" value="demo.wssec.server.UTPasswordCallback" /> 
         <!-- <entry key="user" value="server" /> --> 
         <entry key="decryptionPropFile" value="etc/Server_Decrypt.properties" /> 
         <entry key="encryptionKeyIdentifier" value="IssuerSerial" /> 

         <entry key="signaturePropFile" value="etc/Server_SignVerf.properties" /> 
         <entry key="signatureKeyIdentifier" value="DirectReference" /> 

         <entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" /> 
         <entry key="signatureAlgorithm" value="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> 
        </map> 
       </constructor-arg> 
      </bean> 
     </jaxws:inInterceptors> 
    </jaxws:endpoint> 

</beans> 

我的WSDL文件是:

<?xml version="1.0" encoding="UTF-8"?> 

<wsdl:definitions name="HelloWorld" targetNamespace="http://cxf.apache.org/hello_world_soap_http" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://cxf.apache.org/hello_world_soap_http" 
    xmlns:x1="http://cxf.apache.org/hello_world_soap_http/types" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <wsdl:types> 
     <schema targetNamespace="http://cxf.apache.org/hello_world_soap_http/types" 
      xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 
      <element name="sayHi"> 
       <complexType/> 
      </element> 
      <element name="sayHiResponse"> 
       <complexType> 
        <sequence> 
         <element name="responseType" type="xsd:string"/> 
        </sequence> 
       </complexType> 
      </element> 
      <element name="greetMe"> 
       <complexType> 
        <sequence> 
         <element name="requestType" type="xsd:string"/> 
        </sequence> 
       </complexType> 
      </element> 
      <element name="greetMeResponse"> 
       <complexType> 
        <sequence> 
         <element name="responseType" type="xsd:string"/> 
        </sequence> 
       </complexType> 
      </element> 
      <element name="greetMeOneWay"> 
       <complexType> 
        <sequence> 
         <element name="requestType" type="xsd:string"/> 
        </sequence> 
       </complexType> 
      </element> 
     </schema> 
    </wsdl:types> 

    <wsdl:message name="sayHiRequest"> 
     <wsdl:part element="x1:sayHi" name="in"/> 
    </wsdl:message> 
    <wsdl:message name="sayHiResponse"> 
     <wsdl:part element="x1:sayHiResponse" name="out"/> 
    </wsdl:message> 
    <wsdl:message name="greetMeRequest"> 
     <wsdl:part element="x1:greetMe" name="in"/> 
    </wsdl:message> 
    <wsdl:message name="greetMeResponse"> 
     <wsdl:part element="x1:greetMeResponse" name="out"/> 
    </wsdl:message> 
    <wsdl:message name="greetMeOneWayRequest"> 
     <wsdl:part element="x1:greetMeOneWay" name="in"/> 
    </wsdl:message> 

    <wsdl:portType name="Greeter"> 
     <wsdl:operation name="sayHi"> 
      <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/> 
      <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/> 
     </wsdl:operation> 

     <wsdl:operation name="greetMe"> 
      <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/> 
      <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/> 
     </wsdl:operation> 

     <wsdl:operation name="greetMeOneWay"> 
      <wsdl:input message="tns:greetMeOneWayRequest" name="greetMeOneWayRequest"/> 
     </wsdl:operation> 

    </wsdl:portType> 

    <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter"> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> 

     <wsdl:operation name="sayHi"> 
      <soap:operation soapAction="" style="document"/> 
      <wsdl:input name="sayHiRequest"> 
       <soap:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output name="sayHiResponse"> 
       <soap:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 

     <wsdl:operation name="greetMe"> 
      <soap:operation soapAction="" style="document"/> 
      <wsdl:input name="greetMeRequest"> 
       <soap:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output name="greetMeResponse"> 
       <soap:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 

     <wsdl:operation name="greetMeOneWay"> 
      <soap:operation soapAction="" style="document"/> 
      <wsdl:input name="greetMeOneWayRequest"> 
       <soap:body use="literal"/> 
      </wsdl:input> 
     </wsdl:operation> 
    </wsdl:binding> 

    <wsdl:service name="GreeterService"> 
     <wsdl:port binding="tns:Greeter_SOAPBinding" name="GreeterPort"> 
      <soap:address location="http://localhost:12000/TestingWebWsSecurity/services/GreeterPort"/> 
      <wswa:UsingAddressing xmlns:wswa="http://www.w3.org/2005/02/addressing/wsdl"/> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

的客戶端代碼:

package demo.wssec.client; 

import java.io.Closeable; 

import java.lang.reflect.UndeclaredThrowableException; 
import java.net.URL; 
import java.util.HashMap; 
import java.util.Map; 

import org.apache.cxf.Bus; 
import org.apache.cxf.BusFactory; 
import org.apache.cxf.bus.spring.SpringBusFactory; 
import org.apache.cxf.hello_world_soap_http.Greeter; 
import org.apache.cxf.hello_world_soap_http.GreeterService; 

import org.apache.cxf.ws.security.wss4j.DefaultCryptoCoverageChecker; 
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; 
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; 


public final class Client { 

    private static final String WSU_NS 
     = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"; 

    private Client() { 
    } 

    public static void main(String args[]) throws Exception { 
     try { 

      SpringBusFactory bf = new SpringBusFactory(); 
      URL busFile = Client.class.getResource("wssec.xml"); 
      Bus bus = bf.createBus(busFile.toString()); 
      BusFactory.setDefaultBus(bus); 

      Map<String, Object> outProps = new HashMap<String, Object>(); 
      outProps.put("action", "UsernameToken Timestamp Signature Encrypt"); 

      outProps.put("passwordType", "PasswordDigest"); 

      outProps.put("user", "abcd"); 
      outProps.put("password", "storepassword"); 
      outProps.put("signatureUser", "clientx509v1"); 

      outProps.put("passwordCallbackClass", "demo.wssec.client.UTPasswordCallback"); 

      outProps.put("encryptionUser", "serverx509v1"); 
      outProps.put("encryptionPropFile", "etc/Client_Encrypt.properties"); 
      outProps.put("encryptionKeyIdentifier", "IssuerSerial"); 
      outProps.put("encryptionParts", 
         "{Element}{" + WSU_NS + "}Timestamp;" 
         + "{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"); 

      outProps.put("signaturePropFile", "etc/Client_Sign.properties"); 
      outProps.put("signatureKeyIdentifier", "DirectReference"); 
      outProps.put("signatureParts", 
         "{Element}{" + WSU_NS + "}Timestamp;" 
         + "{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;" 
         + "{}{http://www.w3.org/2005/08/addressing}ReplyTo;"); 

      outProps.put("encryptionKeyTransportAlgorithm", 
         "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"); 
      outProps.put("signatureAlgorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1"); 

      bus.getOutInterceptors().add(new WSS4JOutInterceptor(outProps)); 

      Map<String, Object> inProps = new HashMap<String, Object>(); 

      inProps.put("action", "UsernameToken Timestamp Signature Encrypt"); 
      inProps.put("passwordType", "PasswordText"); 
      inProps.put("passwordCallbackClass", "demo.wssec.client.UTPasswordCallback"); 

      inProps.put("decryptionPropFile", "etc/Client_Sign.properties"); 
      inProps.put("encryptionKeyIdentifier", "IssuerSerial"); 

      inProps.put("signaturePropFile", "etc/Client_Encrypt.properties"); 
      inProps.put("signatureKeyIdentifier", "DirectReference"); 

      inProps.put("encryptionKeyTransportAlgorithm", 
         "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"); 
      inProps.put("signatureAlgorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1"); 

      bus.getInInterceptors().add(new WSS4JInInterceptor(inProps)); 

      // Check to make sure that the SOAP Body and Timestamp were signed, 
      // and that the SOAP Body was encrypted 
      DefaultCryptoCoverageChecker coverageChecker = new DefaultCryptoCoverageChecker(); 
      coverageChecker.setSignBody(true); 
      coverageChecker.setSignTimestamp(true); 
      coverageChecker.setEncryptBody(true); 
      bus.getInInterceptors().add(coverageChecker); 

      GreeterService service = new GreeterService(); 
      Greeter port = service.getGreeterPort(); 

      String[] names = new String[] {"Anne", "Bill", "Chris", "Sachin Tendulkar"}; 
      // make a sequence of 4 invocations 
      for (int i = 0; i < 4; i++) { 
       System.out.println("Invoking greetMe..."); 
       String response = port.greetMe(names[i]); 
       System.out.println("response: " + response + "\n"); 
      } 

      // allow asynchronous resends to occur 
      Thread.sleep(30 * 1000); 

      if (port instanceof Closeable) { 
       ((Closeable)port).close(); 
      } 

      bus.shutdown(true); 

     } catch (UndeclaredThrowableException ex) { 
      ex.getUndeclaredThrowable().printStackTrace(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } finally { 
      System.exit(0); 
     } 
    } 
} 

當我執行客戶端代碼它說:

Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '404: Not Found' when communicating with http://localhost:12000/TestingWebWsSecurity/services/GreeterPort 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1526) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1486) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1305) 
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50) 
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223) 
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) 
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623) 
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) 
    ... 9 more 

javax.xml.ws.WebServiceException: Could not send Message. 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145) 
    at com.sun.proxy.$Proxy40.greetMe(Unknown Source) 
    at demo.wssec.client.Client.main(Client.java:120) 
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '404: Not Found' when communicating with http://localhost:12000/TestingWebWsSecurity/services/GreeterPort 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1526) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1486) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1305) 
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50) 
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223) 
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) 
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:623) 
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) 
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:541) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330) 
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134) 
    ... 2 more 

回答

0

的解決方案是以下內容:更新您的CXF-beans.xml中使用:代替

<cxf:bus> 
     <cxf:inInterceptors> 
      <ref bean="inIntercTest"/> 
     </cxf:inInterceptors> 
     <cxf:outInterceptors>    
      <ref bean="outIntercTest"/>   
     </cxf:outInterceptors> 
    </cxf:bus> 

<cxf:bus> 
     <cxf:features> 
      <cxf:logging /> 
      <wsa:addressing /> 
     </cxf:features> 
    </cxf:bus>