1

I have create Java Classes from the DHL WSDL https://cig.dhl.de/cig-wsdls/com/dpdhl/wsdl/geschaeftskundenversand-api/2.2/geschaeftskundenversand-api-2.2.wsdl.

Now i have all Classes, but no Authentifaction Class. I try this

 GKVAPIServicePortTypeProxy port2 = new GKVAPIServicePortTypeProxy();
        port2.setEndpoint("https://cig.dhl.de/services/sandbox/soap");

     CreateShipmentOrderRequest sh = new CreateShipmentOrderRequest();
        //Setting up shipment;
        .. and so on

        CreateShipmentOrderResponse chr = port2.createShipmentOrder(sh);

But only what i get is, "(401)Authorization Required" How can i set my Authentifiaction ?

Metti
  • 85
  • 1
  • 8
  • Please show **how** you generated your classes. – Mark Rotteveel Oct 11 '18 at 19:51
  • I have that generated over the eclipse Import. I have also a Bindingsub clas where i can the Username und password, i have no idea how to couple the Bindingsub class to GKVAPIServicePortTypeProxy, when i use the Bindingsub class to connect to the Service, the i habe no endpoint Adresse – Metti Oct 11 '18 at 20:05

2 Answers2

4

Hi I h had fixed the 401 problem with adding of the ssl certificate from DHL to my application truststore. But I have the problem that I missing to add the Authentification block to the request.

<soapenv:Header>
      <cis:Authentification>
         <cis:user>user</cis:user>
         <cis:signature>password</cis:signature>
      </cis:Authentification>
 </soapenv:Header>

My try to adding this block resulting in a 'org.quartz.jobexecutionexception: de.vps.icms.exceptions.icmsscriptingexception: java.lang.noclassdeffounderror: org/apache/axis2/saaj/soapenvelopeimpl'exception.

Some idea what I did wrong? Here the Code: public class WSClient {

   public WSClient() {
        try {
            GKVAPIServicePortType port = prepareService();
            String b = BWIConstants.SYSPARAM_DHL_WS_URL;
            CreateShipmentOrderRequest createShipmentOrderRequest = new CreateShipmentOrderRequest();
            CreateShipmentOrderResponse createShipmentOrderResponse =
                port.createShipmentOrder(createShipmentOrderRequest);
            createShipmentOrderResponse.getStatus();

        } catch (Exception e) {
            e.printStackTrace();

        }

    }

    private GKVAPIServicePortType prepareService() throws MalformedURLException {
        // get Service stub

        String pathToClassFolder = getClass().getResource("/").toString();
        String fullwsdlFilePath = pathToClassFolder + "/" + "geschaeftskundenversand-api-2.2.wsdl";
        URL wsdlLocation = new URL(fullwsdlFilePath);

        GVAPI20De service = new GVAPI20De(wsdlLocation);

        // get Service Port
        GKVAPIServicePortType port = service.getPort(GKVAPIServicePortType.class);

        // overwrite Endpoint
        Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://cig.dhl.de/services/sandbox/soap");

        // overwrite BasicAuth Username and Password
        // requestContext.put(BindingProvider.USERNAME_PROPERTY, cigUser);
        // requestContext.put(BindingProvider.PASSWORD_PROPERTY, cigPass);

        // Add authentication Handler
        Binding binding = ((BindingProvider) port).getBinding();
        List<Handler> handlerChain = binding.getHandlerChain();
        handlerChain.add(
            new AuthenticationHandler(BWIConstants.SYSPARAM_DHL_WS_USER, BWIConstants.SYSPARAM_DHL_WS_SIGNATURE));
        binding.setHandlerChain(handlerChain);

        return port;
    }

}

public class AuthenticationHandler implements SOAPHandler<SOAPMessageContext> {

    private String USER = "";
    private String PASSWORD = "";

    public AuthenticationHandler(final String user, final String password) {
        USER = user;
        PASSWORD = password;
    }

    /**
     * {@inheritDoc}
     */
    public void close(final MessageContext context) {
        // nothing to do
    }

    /**
     * {@inheritDoc}
     */
    public Set<QName> getHeaders() {
        // nothing to do
        return null;
    }

    /**
     * {@inheritDoc}
     */
    public boolean handleFault(final SOAPMessageContext context) {
        // nothing to do
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public boolean handleMessage(final SOAPMessageContext context) {
        if (isOutboundMessage(context)) {
            try {
                // get/create the map of HTTP headers
                Map<Object, Object> headers = (Map<Object, Object>) context.get(MessageContext.HTTP_REQUEST_HEADERS);
                if (headers == null) {
                    headers = new HashMap<Object, Object>();
                    context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
                }

                // add custom HTTP header (deactivate HTTP keepAlive)
                String headerName = "Connection";
                List<String> headerValues = new ArrayList<String>();
                headerValues.add("Close");
                headers.put(headerName, headerValues);

                SOAPMessage message = context.getMessage();
                SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();

                SOAPHeader header;
                if (envelope.getHeader() == null) {
                    header = envelope.addHeader();
                } else {
                    header = envelope.getHeader();
                }

                // add the Authentification element
                SOAPElement auth = header.addHeaderElement(
                    envelope.createName("Authentification", "cis", "http://dhl.de/webservice/cisbase"));
                SOAPElement user =
                    auth.addChildElement(envelope.createName("user", "cis", "http://dhl.de/webservice/cisbase"));
                user.setValue(USER);
                SOAPElement signature =
                    auth.addChildElement(envelope.createName("signature", "cis", "http://dhl.de/webservice/cisbase"));
                signature.setValue(PASSWORD);
                SOAPElement type =
                    auth.addChildElement(envelope.createName("type", "cis", "http://dhl.de/webservice/cisbase"));
                type.setValue("0");

                // save changes
                message.saveChanges();
            } catch (SOAPException ex) {
                throw new RuntimeException("Failed to add SOAP headers for authentication.", ex);
            }
        }
        return true;
    }

    private boolean isOutboundMessage(final MessageContext context) {
        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        return outboundProperty.booleanValue();
    }
}
0

Using basic authentication, you would first Base64 encode your username:password - there's online sites that will do it but beware as likely not a good idea to do it if it refers to DHL in anyway, e.g. they could swipe your credentials.
You then get the Request Context of the port, create a map of the headers and add an Authorization header. Finally you add that back to the request context.

Example: Note, I purposely generated bad base64 encoding so you would likely not be able to decode it and see it properly formatted with the "username:password"

        GVAPI20De service1 = new GVAPI20De();

        GKVAPIServicePortType port2 = service1.getGKVAPISOAP11Port0();

        CreateShipmentOrderRequest sh = new CreateShipmentOrderRequest();
        //Setting up shipment;

        Map<String, Object> req_ctx = ((BindingProvider)port2).getRequestContext();

        //you may not need this and can try commenting it out
        req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://cig.dhl.de/cig-wsdls/com/dpdhl/wsdl/geschaeftskundenversand-api/2.2/geschaeftskundenversand-api-2.2.wsdl");

        //optional timeout
        req_ctx.put("javax.xml.ws.client.connectionTimeout", "60000");

        Map<String, List<String>> headers = new HashMap<String, List<String>>();
        headers.put("Authorization", Collections.singletonList("Basic c3gh567sd4689k11lg=="));

        req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);

        CreateShipmentOrderResponse chr = port2.createShipmentOrder(sh)
JGlass
  • 1,427
  • 2
  • 12
  • 26
  • When i try this, i get a cast error. de.dhl.webservices.businesscustomershipping.GKVAPIServicePortTypeProxy cannot be cast to javax.xml.ws.BindingProvider. I also try it with the GKVAPIServicePortType cl – Metti Oct 12 '18 at 05:49
  • It looks like you might be using the wrong service? The client code generated for me is different. Updated my answer adding correct service. – JGlass Oct 12 '18 at 13:48
  • How have you import the WSDL, when i init the GVAPI Objekt, then they create many Methodes in my Projekt like " @Override public GKVAPIServicePortType getGKVAPISOAP11port0(URL portAddress) throws ServiceException { // TODO Auto-generated method stub return null; } " – Metti Oct 15 '18 at 06:11
  • 1
    I use Eclipse IDE and also have JBoss installed so I used JAX-WS to import the wsdl and generate all the stubs. I do believe you should be using the generated service "GVAPI20De" and port "GKVAPIServicePortType" - have you tried it to see if the code works? I don't have any authentication credentials so I cannot try it myself. – JGlass Oct 15 '18 at 13:12
  • This was my fail, i used eclispe + apache to import wsdl. Now i Use Jboss and its work perfect. Thank you – Metti Oct 16 '18 at 07:38
  • You're welcome Metti, glad you got it going and thanks for accepting the answer! – JGlass Oct 16 '18 at 13:24