Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Authentication Headers to SOAP Request

I'm using Spring Integration 4.2.4.RELEASE and it doesn't seem to want to add my Authorization Header to the SOAP requests.

Here's the relevant spring-integration configuration:

<ws:outbound-gateway uri="${soap.ws.url}" message-factory="messageFactory" message-sender="messageSender"/>

<bean id="httpClientFactory" class="com.myorg.http.HttpClientFactoryBean">
    <property name="credentials" ref="httpClientCredentials"/>
</bean>

<bean name="messageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
    <property name="credentials" ref="httpClientCredentials"/>
    <property name="httpClient" ref="httpClientFactory"/>
</bean>

<bean id="httpClientCredentials" class="org.apache.http.auth.UsernamePasswordCredentials">
    <constructor-arg value="${username}"/>
    <constructor-arg value="${password}"/>
</bean>

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
    <property name="soapVersion">
        <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11"/>
    </property>
    <property name="messageFactory" ref="myMessageFactory" />
</bean>

<bean id="myMessageFactory" class="com.myorg.soap.CustomMessageFactory" />

Here's the custom messageFactory class

package com.myorg.soap;

import com.sun.xml.messaging.saaj.soap.MessageFactoryImpl;
import com.sun.xml.messaging.saaj.soap.ver1_1.Message1_1Impl;

import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import java.io.IOException;
import java.io.InputStream;

/**
 * Custom Message Factory.
 */
public class CustomMessageFactory extends MessageFactoryImpl {

    /**
     * Class Constructor.
     *
     * @return Message1_1Impl
     * @throws SOAPException when there is a SOAP error.
     */
    @Override
    public SOAPMessage createMessage() throws SOAPException {
        return new Message1_1Impl();
    }

    /**
     * Create a new message.
     *
     * @param mimeHeaders headers to add to the message
     * @param in input stream to use in the message.
     * @return New SOAP 1.1 message.
     * @throws IOException when there is an IO error
     * @throws SOAPException when there is a SOAP error
     */
    @Override
    public SOAPMessage createMessage(final MimeHeaders mimeHeaders, final InputStream in)
            throws IOException, SOAPException {
        MimeHeaders headers = mimeHeaders;
        if (headers == null) {
            headers = new MimeHeaders();
        }
        headers.setHeader("Content-Type", "text/xml");

        Message1_1Impl msg = new Message1_1Impl(headers, in);
        msg.setLazyAttachments(this.lazyAttachments);
        return msg;
    }
}

Here's the custom httpClientFactory class

package com.myorg.http;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.FactoryBean;

/**
 * Provide an HttpClient factory bean, so we can configure the ODE web service client to use TLS1.1 and TLS1.2.
 */
public class HttpClientFactoryBean implements FactoryBean<HttpClient> {
    /**
     * Default socket timeout will be 15 seconds.
     */
    private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (15 * 1000);

    /**
     * Max connections defaults to 5.
     */
    private static final int MAX_CONNECTIONS = 5;

    /**
     * Local storage for credentials.
     */
    private Credentials credentials;

    @Override
    public HttpClient getObject() throws Exception {
        HttpClientBuilder builder = HttpClientBuilder.create();

        SocketConfig socketConfig = SocketConfig.custom()
                .setSoTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS)
                .build();

        builder.useSystemProperties()
                .setMaxConnTotal(MAX_CONNECTIONS)
                .setDefaultSocketConfig(socketConfig);

        if (credentials != null) {
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, credentials);
            builder.setDefaultCredentialsProvider(credentialsProvider);
        }

        return builder.build();
    }

    @Override
    public Class<?> getObjectType() {
        return HttpClient.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    public Credentials getCredentials() {
        return credentials;
    }

    public void setCredentials(final Credentials credentials) {
        this.credentials = credentials;
    }
}

The problem that I'm seeing is that the Authorization header doesn't seem to be set on the request. What am I missing?

like image 653
Craig Gardner Avatar asked Nov 19 '25 19:11

Craig Gardner


1 Answers

I follow the spring consume webservice guide " https://spring.io/guides/gs/consuming-web-service/#initial " there was a example too. But there is not how to add basic authorization. So you can use like this

public class WebServiceMessageSenderWithAuth extends HttpUrlConnectionMessageSender {
    
    private String username;

    private String password;

    @Override
    protected void prepareConnection(HttpURLConnection connection) throws IOException {
        BASE64Encoder enc = new sun.misc.BASE64Encoder();
        String userpassword = username+":"+password;
        String encodedAuthorization = enc.encode( userpassword.getBytes() );
        connection.setRequestProperty("Authorization", "Basic " + encodedAuthorization);

        super.prepareConnection(connection);
    }
}

and

public YourClient yourClient(Jaxb2Marshaller marshaller){
    YourClient client = new YourClient();
    
    WebServiceTemplate template = client.getWebServiceTemplate();
    template.setMessageSender(new WebServiceMessageSenderWithAuth());
    
    client.setDefaultUri("http://examplesap.com/xx/WebService/soap1.1x");
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    return client;
}

And call..

return (YourResponseModel) getWebServiceTemplate()
                .marshalSendAndReceive(url, request,
                        new SoapActionCallback(
                        "http://examplesap.com/xx/WebService/soap1.1x"));
like image 140
Alper Karaağaçlı Avatar answered Nov 22 '25 09:11

Alper Karaağaçlı



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!