带有 eclipse MOXY JAXBContextFactory 的 Aache-CXF WS 客户端不发送安全标头

问题描述 投票:0回答:1

我使用 Apache-CXF WS 作为 SOAP 客户端。侧面 SOAP 端点具有安全性(用户名/密码)要求。我还使用 org.eclipse.persistence.eclipselink 来更改 JAXBContextFactory,因为默认工厂会在请求中生成冗余名称空间。

使用默认的 JAXB 客户端在标头中发送用户名令牌:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  
  <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1">
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-5ec36563-1289-4272-a820-2df93385246a">
        <wsse:Username>username</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>

  <soap:Body>
   ...
  </soap:Body>
</soap:Envelope>

但是使用 MOXY JAXBContextFactory 客户端不会发送安全标头:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

  >> NO HEADER <<

  <soap:Body>
    ...
  </soap:Body>
</soap:Envelope>

我尝试在文档中查找一些信息,但没有成功。

我的 CXF SOAP 客户端配置:

<jaxws:client id="side_service_client"
        wsdlLocation="side_service.wsdl"
        serviceClass="com.example.SideService"
        address="${side_service_url}"
        xmlns:bfns="http://www.example.com/side_service/"
        serviceName="bfns:side_service">

        <jaxws:properties>
            <entry key="security.username" value="${sideServiceUsername}"/>
            <entry key="security.password" value="${sideServicePassword}"/>
            <entry key="schema-validation-enabled" value="false"/>
        </jaxws:properties>
</jaxws:client>

Apache CXF 版本 - 3.4.10 org.eclipse.persistence.eclipselink 版本 - 2.6.9

也许有人已经遇到过这样的问题并且知道解决方案的方向?

感谢您的回答=)

java apache soap cxf moxy
1个回答
0
投票

我的问题找到了解决方案。

  1. cxf-rt-ws-policy 依赖项添加到我的项目中:
<dependency>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-rt-ws-policy</artifactId>
   <version>${apache.cxf.version}</version>
</dependency>
  1. 创建并添加拦截器:

服务器密码回调.java

package com.your.domain.configuration;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.wss4j.common.ext.WSPasswordCallback;

/**
 * Setup username token to outbound message manually.
 */
public class ServerPasswordCallback implements CallbackHandler {

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        pc.setPassword("YOUR_PASSWORD_VALUE");
    }
}

springAppContext.xml

...
<bean id="myPasswordCallback" class="com.your.domain.configuration.ServerPasswordCallback"/>

<jaxws:client id="some_client"
       wsdlLocation="some_client.wsdl"
       serviceClass="com.your.domain.ServiceClass"
       address="${addressUrl}">

       ...

       <jaxws:outInterceptors>
            <bean id="securityInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
                <constructor-arg>
                    <map>
                        <entry key="action" value="UsernameToken"/>
                        <entry key="passwordType" value="PasswordText"/>
                        <entry key="user" value="YOUR_USERNAME"/>
                        <entry key="passwordCallbackRef" value-ref="myPasswordCallback"/>
                    </map>
                </constructor-arg>
            </bean>
        </jaxws:outInterceptors>

       ...

</jaxws:client>
...
© www.soinside.com 2019 - 2024. All rights reserved.