-->

Spring Web Service Template: Add username token

2019-03-31 18:48发布

问题:

I have a web app that acts as a client to a Jax-WS web service implemented using Spring WS. The Spring WS is configured to require a username token in the SOAP header. In the web app I plan to use the Spring web service template but I can't seem to find any examples which show how to add a UsernameToken to the outgoing request.

Can someone point me in the right direction?

Thanks.

回答1:

You have to use Interceptors. See Chapter 7. Securing your Web services with Spring-WS.

The configuration would be something like this

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <property name="marshaller" ref="marshaller" />
    <property name="unmarshaller" ref="marshaller" />
    <property name="defaultUri"
        value="http://localhost:8080/ws-demo/myws" />
    <property name="interceptors">
        <list>
            <ref bean="wsSecurityInterceptor" />
        </list>
    </property>
</bean>

<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="securementActions" value="UsernameToken"/>
    <property name="securementUsername" value="Ernie"/>
    <property name="securementPassword" value="Bert"/>
</bean>


回答2:

in addition to jddsantaella's answer, the client class can use SAAJ to add username token in the SOAP header:

OrganisationPortfolioRequest request = WS_CLIENT_FACTORY.createOrganisationsPortfolioRequest();
OrganisationPortfolioResponse response;

response = (OrganisationPortfolioResponse) webServiceTemplate.marshalSendAndReceive(request, 
            new WebServiceMessageCallback() {
        public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
            SaajSoapMessage soapMessage = (SaajSoapMessage) message;
            SoapEnvelope envelope = soapMessage.getEnvelope();
            envelope.addNamespaceDeclaration("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
            envelope.addNamespaceDeclaration("s", "http://company.com/ws/security.xsd");

            SoapHeaderElement username =  soapMessage.getSoapHeader().addHeaderElement(new QName("http://company.com/ws/security.xsd", "username", "s"));
            username.setText(getCurrentUser.getUsername());
        }
    });
response.getResults();


回答3:

Above given answer is used for xml.

I mention here annotation base configuration for usernameToken security policy for web service.

Add this configuration with spring boot client

@Bean
public WebServiceTemplate webServiceTemplate() {
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setMarshaller(marshaller());
    webServiceTemplate.setUnmarshaller(marshaller());
    webServiceTemplate.setDefaultUri("http://localhost:8080/ws");
    webServiceTemplate.setInterceptors(new ClientInterceptor[] {wsSecurityInterceptor()}); 
    return webServiceTemplate;
}

@Bean
public Wss4jSecurityInterceptor wsSecurityInterceptor() {
    Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
    wss4jSecurityInterceptor.setSecurementActions(WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.USERNAME_TOKEN);
    wss4jSecurityInterceptor.setSecurementPasswordType(WSConstants.PW_TEXT);
    wss4jSecurityInterceptor.setSecurementUsername("user");
    wss4jSecurityInterceptor.setSecurementPassword("password");
    return wss4jSecurityInterceptor;
}