Search code examples
soapcxf

Cybersource org.apache.cxf.binding.soap.SoapFault: Security processing failed USING CXF


    package com.cybersource.schemas.transaction_data.transactionprocessor;

    import java.io.IOException;
    import java.math.BigInteger;
    import java.net.MalformedURLException;
    import java.net.URL;
    imp ort java.rmi.RemoteException;
    import java.util.HashMap;
    import java.util.Map;

    import org.apache.cxf.version.Version;

    import com.cybersource.schemas.transaction_data_1.BillTo;
    import com.cybersource.schemas.transaction_data_1.CCAuthService;
    import com.cybersource.schemas.transaction_data_1.Card;
    import com.cybersource.schemas.transaction_data_1.Item;
    import com.cybersource.schemas.transaction_data_1.PurchaseTotals;
    import com.cybersource.schemas.transaction_data_1.ReplyMessage;
    import com.cybersource.schemas.transaction_data_1.RequestMessage;

    import org.apache.cxf.endpoint.Client;
    import org.apache.cxf.endpoint.Endpoint;
    import org.apache.cxf.frontend.ClientProxy;
    import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
    import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
    import org.apache.ws.security.WSConstants;
    import org.apache.ws.security.WSPasswordCallback;
    //import org.apache.wss4j.common.ext.WSPasswordCallback; 
    import org.apache.ws.security.handler.WSHandlerConstants;

    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException; 
    public class CybersourceClientExample {

        // Replace the MERCHANT_ID and MERCHANT_KEY with the appropriate --donevalues.

        private static final String MERCHANT_ID = "MERCHANT_ID ";
        private static final String MERCHANT_KEY = "MERCHANT_KEY ";

        private static final String SERVER_URL = "https://ics2wstesta.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.142.wsdl";

        private static final String CLIENT_LIB_VERSION = Version.getCompleteVersionString() + "/1.5.10"; // CXF Version / WSS4J Version
        private static final String CLIENT_LIBRARY = "Java CXF WSS4J";
        private static final String CLIENT_ENV = System.getProperty("os.name") + "/" +
                                                System.getProperty("os.version") + "/" +
                                                System.getProperty("java.vendor") + "/" +
                                                System.getProperty("java.version");

        public static void main(String[] args) throws RemoteException, MalformedURLException {
            RequestMessage request = new RequestMessage();

            // To help Cybersource troubleshoot any problems that you may encounter,
            // include the following information about the client.
            addClientLibraryInfo(request);

            request.setMerchantID(MERCHANT_ID);

            // Internal Transaction Reference Code for the Merchant
            request.setMerchantReferenceCode("222222");

            // Here we are telling the client that we are going to run an AUTH.
            request.setCcAuthService(new CCAuthService());
            request.getCcAuthService().setRun("true");

            request.setBillTo(buildBillTo());
            request.setCard(buildCard());
            request.setPurchaseTotals(buildPurchaseTotals());

            request.getItem().add(buildItem("0", "12.34", "2"));
            request.getItem().add(buildItem("1", "56.78", "1"));

            ITransactionProcessor processor = new TransactionProcessor(new URL(SERVER_URL)).getPortXML();

            //  Add WS-Security Headers to the Request
            addSecurityValues(processor);

            ReplyMessage reply = processor.runTransaction(request);

            System.out.println("decision = " + reply.getDecision());
            System.out.println("reasonCode = " + reply.getReasonCode());
            System.out.println("requestID = " + reply.getRequestID());
            System.out.println("requestToken = " + reply.getRequestToken());
            System.out.println("ccAuthReply.reasonCode = " + reply.getCcAuthReply().getReasonCode());
        }

        private static void addClientLibraryInfo(RequestMessage request) {
            request.setClientLibrary(CLIENT_LIBRARY);
            request.setClientLibraryVersion(CLIENT_LIB_VERSION);
            request.setClientEnvironment(CLIENT_ENV);
        }

        private static Item buildItem(String id, String unitPrice, String quantity) {
            Item item = new Item();
            item.setId(new BigInteger(id));
            item.setUnitPrice(unitPrice);
            item.setQuantity(quantity);
            return item;
        }

        private static PurchaseTotals buildPurchaseTotals() {
            PurchaseTotals purchaseTotals = new PurchaseTotals();
            purchaseTotals.setCurrency("USD");
            purchaseTotals.setGrandTotalAmount("100");
            return purchaseTotals;
        }

        private static Card buildCard() {
            Card card = new Card();
            card.setAccountNumber("4111111111111111");
            card.setExpirationMonth(new BigInteger("12"));
            card.setExpirationYear(new BigInteger("2020"));
            return card;
        }

        private static BillTo buildBillTo() {
            BillTo billTo = new BillTo();
            billTo.setFirstName("John");
            billTo.setLastName("Doe");
            billTo.setStreet1("1295 Charleston Road");
            billTo.setCity("Mountain View");
            billTo.setState("CA");
            billTo.setPostalCode("94043");
            billTo.setCountry("US");
            billTo.setEmail("null@cybersource.com");
            billTo.setIpAddress("10.7.111.111");
            return billTo;
        }

        private static void addSecurityValues(ITransactionProcessor processor) {
            Client client = ClientProxy.getClient(processor);
            Endpoint endpoint = client.getEndpoint();

            // We'll have to add the Username and Password properties to an OutInterceptor
            HashMap<String, Object> outHeaders = new HashMap<String, Object>();
            outHeaders.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
            outHeaders.put(WSHandlerConstants.USER, MERCHANT_ID);
            outHeaders.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
            outHeaders.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordHandler.class.getName());




            WSS4JOutInterceptor interceptor = new WSS4JOutInterceptor(outHeaders);
            endpoint.getOutInterceptors().add(interceptor);
        }

        public static class ClientPasswordHandler implements CallbackHandler {

            @Override
            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
                for (Callback callback : callbacks) {
                    if ((WSPasswordCallback)callback instanceof WSPasswordCallback) {
                    WSPasswordCallback passwordCallback = (WSPasswordCallback) callback;
                    passwordCallback.setPassword(MERCHANT_KEY);
                    }
                }
            }
        }
        }

I am facing the following error. Please help.

Dec 04, 2017 8:15:00 AM org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL INFO: Creating Service {urn:schemas-cybersource-com:transaction-data:TransactionProcessor}TransactionProcessor from WSDL: https://ics2wstesta.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.142.wsdl Dec 04, 2017 8:15:03 AM org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging WARNING: Interceptor for {urn:schemas-cybersource-com:transaction-data:TransactionProcessor}TransactionProcessor#{urn:schemas-cybersource-com:transaction-data:TransactionProcessor}runTransaction has thrown exception, unwinding now org.apache.cxf.binding.soap.SoapFault: Security processing failed. at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessageInternal(WSS4JOutInterceptor.java:269) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:135) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:122) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:518) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:427) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:328) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:281) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139) at com.sun.proxy.$Proxy36.runTransaction(Unknown Source) at com.cybersource.schemas.transaction_data.transactionprocessor.CybersourceClientExample.main(CybersourceClientExample.java:77) Caused by: org.apache.wss4j.common.ext.WSSecurityException: WSHandler: password callback failed Original Exception was java.lang.ClassCastException: org.apache.wss4j.common.ext.WSPasswordCallback cannot be cast to org.apache.ws.security.WSPasswordCallback at org.apache.wss4j.dom.handler.WSHandler.performPasswordCallback(WSHandler.java:1172) at org.apache.wss4j.dom.handler.WSHandler.getPasswordCB(WSHandler.java:1130) at org.apache.wss4j.dom.action.UsernameTokenAction.execute(UsernameTokenAction.java:43) at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:234) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor.access$100(WSS4JOutInterceptor.java:54) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessageInternal(WSS4JOutInterceptor.java:261) ... 11 more Caused by: java.lang.ClassCastException: org.apache.wss4j.common.ext.WSPasswordCallback cannot be cast to org.apache.ws.security.WSPasswordCallback at com.cybersource.schemas.transaction_data.transactionprocessor.CybersourceClientExample$ClientPasswordHandler.handle(CybersourceClientExample.java:152) at org.apache.wss4j.dom.handler.WSHandler.performPasswordCallback(WSHandler.java:1170) ... 16 more Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Security processing failed. at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161) at com.sun.proxy.$Proxy36.runTransaction(Unknown Source) at com.cybersource.schemas.transaction_data.transactionprocessor.CybersourceClientExample.main(CybersourceClientExample.java:77) Caused by: org.apache.wss4j.common.ext.WSSecurityException: WSHandler: password callback failed Original Exception was java.lang.ClassCastException: org.apache.wss4j.common.ext.WSPasswordCallback cannot be cast to org.apache.ws.security.WSPasswordCallback at org.apache.wss4j.dom.handler.WSHandler.performPasswordCallback(WSHandler.java:1172) at org.apache.wss4j.dom.handler.WSHandler.getPasswordCB(WSHandler.java:1130) at org.apache.wss4j.dom.action.UsernameTokenAction.execute(UsernameTokenAction.java:43) at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:234) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor.access$100(WSS4JOutInterceptor.java:54) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessageInternal(WSS4JOutInterceptor.java:261) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:135) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:122) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:518) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:427) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:328) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:281) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139) ... 2 more Caused by: java.lang.ClassCastException: org.apache.wss4j.common.ext.WSPasswordCallback cannot be cast to org.apache.ws.security.WSPasswordCallback at com.cybersource.schemas.transaction_data.transactionprocessor.CybersourceClientExample$ClientPasswordHandler.handle(CybersourceClientExample.java:152) at org.apache.wss4j.dom.handler.WSHandler.performPasswordCallback(WSHandler.java:1170) ... 16 more


Solution

  • "Caused by: java.lang.ClassCastException: org.apache.wss4j.common.ext.WSPasswordCallback cannot be cast to org.apache.ws.security.WSPasswordCallback at " - looks like you are mixing WSS4J versions incorrectly. Have you verified that all of the WSS4J jars on the classpath have the same version? Also have you checked that the WSS4J version is the correct one that should be used with the version of CXF you are using?