1 Reply Latest reply on Aug 28, 2013 12:48 AM by Joseph Hwang

    org.apache.cxf.ws.policy.PolicyException: Cannot encrypt data

    Joseph Hwang Novice

      This is my sample WS-Security project.

       

      ===== IHelloWorld Interface

      @WebService ( targetNamespace = "http://www.aaa.com/jbossws/ws-extensions/wssecurity" )
      @PolicySets({"WS-Addressing","WS-SP-EX223_WSS11_Anonymous_X509_Sign_Encrypt"})
      public interface IHelloWorld {

         @WebMethod
         @WebResult
         public String sayHello(@WebParam String name);
      }

       

      ===== CallbackHandler class

      public class KeystorePasswordCallback implements CallbackHandler {

         private Map<String, String> passwords = new HashMap<String, String>();   

         public KeystorePasswordCallback() {    passwords.put("joseph", "password");     // adding only one user and password
         }

       

         @Override
         public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            // TODO Auto-generated method stub
           for (int i = 0; i < callbacks.length; i++) {        
              WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];         
              String pass = passwords.get(pc.getIdentifier());        
              if (pass != null) {           
                 pc.setPassword(pass);           
                 return;        
              }     
            }
         }

         public void setAliasPassword(String alias, String password) {     
            passwords.put(alias, password);  
         }

      }

       

      ====== joseph.properties file

      org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

      org.apache.ws.security.crypto.merlin.keystore.type=jks

      org.apache.ws.security.crypto.merlin.keystore.password=password

      org.apache.ws.security.crypto.merlin.keystore.alias=joseph

      org.apache.ws.security.crypto.merlin.keystore.file=META-INF/joseph.jks

       

      ====== client

      public class WSSClient {

       

         private final String serviceURL="http://localhost:8080/WSSHelloWorld/HelloWorld";

         private IHelloWorld proxy;

       

         public WSSClient() throws IOException {

            QName serviceName = new QName("http://www.aaa.com/jbossws/ws-extensions/wssecurity", "HelloWorldService");

            URL wsdlURL = new URL(serviceURL + "?wsdl");

            Service service = Service.create(wsdlURL, serviceName);

            proxy = (IHelloWorld)service.getPort(IHelloWorld.class);

       

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES,  Thread.currentThread().getContextClassLoader().getResource("META-INF/joseph.properties"));

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES,  Thread.currentThread().getContextClassLoader().getResource("META-INF/joseph.properties"));

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_USERNAME, "joseph");   // same signature_username

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.ENCRYPT_USERNAME, "joseph");   // same encrypt_username

         }

       

         public String callMethd(String name) {

            return proxy.sayHello(name); // this method throws exception

         }

       

      joseph.jks file is generated with java keytool command like below,

       

      > keytool genkey alias joseph keystore joseph.jks keyalg RSA validity 180

       

      Web Service deployment is ok, but client proxy.sayHello throws following exception.

       

      Caused by: org.apache.cxf.ws.policy.PolicyException: Cannot encrypt data

         at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.policyNotAsserted(AbstractBindingBuilder.java:294)

         at org.apache.cxf.ws.security.wss4j.policyhandlers.SymmetricBindingHandler.doEncryptionDerived(SymmetricBindingHandler.java:497)

         at org.apache.cxf.ws.security.wss4j.policyhandlers.SymmetricBindingHandler.doEncryption

       

      In WS-Security - JBoss Web Services - Project Documentation Editor document, both signature and encryption jks files are used. Each server and client side has  its username and password.

      I have no idea how to generate signature and encryption jks files and username.

      Pls, inform me how fix this exception.

       

      I need your advice, Thanks in advance.

      Best regards.

        • 1. Re: org.apache.cxf.ws.policy.PolicyException: Cannot encrypt data
          Joseph Hwang Novice

          I generated server and client jks key files and added 2 key files into projects.

          In client codes binding was successful.

           

             QName serviceName = new QName("http://www.aaa.com/jbossws/ws-extensions/wssecurity", "HelloWorldService");

             URL wsdlURL = new URL(serviceURL + "?wsdl");

             Service service = Service.create(wsdlURL, serviceName);

             proxy = (IHelloWorld)service.getPort(IHelloWorld.class);

           

             ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());

             ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/client.properties"));

             ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/client.properties"));

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_USERNAME, "client");

            ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.ENCRYPT_USERNAME, "server");

           

          Above client codes worked well.

           

          This time I added org.jboss.ws.api.annotation.EndpointConfig annotation to web service class

           

          @WebService(
            portName = "HelloWorldServicePort",
            serviceName = "HelloWorldService",
            targetNamespace = "http://www.aaa.com/jbossws/ws-extensions/wssecurity",
            endpointInterface = "com.aaa.ws.IHelloWorld"
          )
          @PolicySets({"WS-Addressing","WS-SP-EX223_WSS11_Anonymous_X509_Sign_Encrypt"})
          @EndpointConfig(configFile = "WEB-INF/jaxws-endpoint-config.xml", configName = "Custom WS-Security Endpoint") // this line DOES NOT WORK!!!
          public class HelloWorld implements IHelloWorld {

              @Override
              public String sayHello(String name) {
                   // TODO Auto-generated method stub
                 return "Hello " + name;
          }

          }

           

          org.jboss.ws.api.annotation.EndpointConfig annotation did not work. This annotation didn't throw exception of misprinting.

           

          ======= jaxws-endpoint-config.xml

          <endpoint-config>   

            <config-name>Custom WS-Security Endpoint</config-name>   

           

            <property>     

             <property-name>ws-security.signature.properties</property-name>     

             <property-value>META-INF/server.properties</property-value>   

            </property>   

           

            <property>     

             <property-name>ws-security.encryption.properties</property-name>     

             <property-value>META-INF/server.properties</property-value>   

            </property>   

           

            <property>     

             <property-name>ws-security.signature.username</property-name>     

             <property-value>client</property-value>   

            </property>   

           

            <property>     

             <property-name>ws-security.encryption.username</property-name>     

             <property-value>server</property-value>   

            </property>   

           

            <property>     

             <property-name>ws-security.callback-handler</property-name>     

             <property-value>com.aaa.ws.KeystorePasswordCallback_ Hello, I am misprinting!!!</property-value>   

            </property> 

          </endpoint-config>

           

          My web browser threw following exception,

           

          Context Path:   /WSSHelloWorld

           

          Servlet Path: /index.jsp

           

          Path Info: null

           

          Query String: null

           

          Stack Trace

          org.apache.jasper.JasperException: javax.xml.ws.soap.SOAPFaultException: Cannot encrypt data

          org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:409)

          org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:321)

           

          ...

          Is it my coding error or bug?

          Your advice will be appreciated! Thanks.