【问题标题】:Camel CXF SOAP API Consumer with https and Security Header带有 https 和安全标头的 Camel CXF SOAP API 消费者
【发布时间】:2023-01-09 20:29:36
【问题描述】:

我目前面临的问题是,我无法通过 camel-cxf 使用 SOAP 网络服务。例外情况如下:


org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied:
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}TransportBinding: Received Timestamp does not match the requirements
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}IncludeTimestamp
        at org.apache.cxf.ws.policy.AssertionInfoMap.checkEffectivePolicy(AssertionInfoMap.java:179) ~[109:org.apache.cxf.cxf-rt-ws-policy:3.2.6]
        at org.apache.cxf.ws.policy.PolicyVerificationInInterceptor.handle(PolicyVerificationInInterceptor.java:102) ~[109:org.apache.cxf.cxf-rt-ws-policy:3.2.6]
        at org.apache.cxf.ws.policy.AbstractPolicyInterceptor.handleMessage(AbstractPolicyInterceptor.java:44) ~[109:org.apache.cxf.cxf-rt-ws-policy:3.2.6]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[78:org.apache.cxf.cxf-core:3.2.6]
        at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:813) [78:org.apache.cxf.cxf-core:3.2.6]
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1695) [102:org.apache.cxf.cxf-rt-transports-http:3.2.6]
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream$1.run(HTTPConduit.java:1194) [102:org.apache.cxf.cxf-rt-transports-http:3.2.6]
        at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$3.run(AutomaticWorkQueueImpl.java:421) [78:org.apache.cxf.cxf-core:3.2.6]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
        at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$AWQThreadFactory$1.run(AutomaticWorkQueueImpl.java:346) [78:org.apache.cxf.cxf-core:3.2.6]
        at java.lang.Thread.run(Thread.java:748) [?:?]

SOAP 回答以下问题:


<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</faultcode><faultstring xml:lang="de-DE">An error occurred when verifying security for the message.</faultstring></s:Fault></s:Body></s:Envelope>

我使用 Maven cxf-codegen-plugin 通过 wsdl2java goal 生成 Java 类。 wsdl 的安全部分如下所示:


<wsp:Policy wsu:Id="BasicHttpBinding_IUserManagementService_policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                <wsp:Policy>
                    <sp:TransportToken>
                        <wsp:Policy>
                            <sp:HttpsToken RequireClientCertificate="false"/>
                        </wsp:Policy>
                    </sp:TransportToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic256/>
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Lax/>
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:IncludeTimestamp/>
                </wsp:Policy>
            </sp:TransportBinding>
            <sp:SignedSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                <wsp:Policy>
                    <sp:UsernameToken
                            sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                        <wsp:Policy>
                            <sp:WssUsernameToken10/>
                        </wsp:Policy>
                    </sp:UsernameToken>
                </wsp:Policy>
            </sp:SignedSupportingTokens>
            <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                <wsp:Policy/>
            </sp:Wss10>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

我想使用UsernameToken 身份验证。

Maven 依赖项:

骆驼版本:2.20.3


<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-core</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-blueprint</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-cxf</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-soap-starter</artifactId>
    <scope>provided</scope>
</dependency>


<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-ws-security</artifactId>
    <version>3.2.6</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-ws-policy</artifactId>
    <version>3.2.6</version>
    <scope>provided</scope>
</dependency>

我尝试通过 SoapUI 连接到 api,一切正常。无论是使用 SoapUI 的身份验证部分还是在 SoapHeader 中指定安全部分,两者都有效。

我的骆驼路线建设者看起来像这样:


SoapJaxbDataFormat soap = new SoapJaxbDataFormat("org.tempuri", new ServiceInterfaceStrategy(IUserManagementService.class, true));


from("direct:userdata.soap.requests")
// .marshal(soap) // not sure, if I need to marshal here
.to("cxf://{{SOAP_URL}}" +
        "?serviceClass=org.tempuri.IUserManagementService" +
        "&serviceName={http://tempuri.org/}UserManagementService" +
        "&endpointName={http://tempuri.org/}BasicHttpBinding_IUserManagementService" +
        "&wsdlURL={{WSDL_URL}}" +
        "&dataFormat=MESSAGE" +
        "&username={{SOAP_USERNAME}}" +
        "&password={{SOAP_PASSWORD}}" +
          "&allowStreaming=false");

我像这样发送到队列:


@EndpointInject(uri = "direct:userdata.soap.requests")
Endpoint endpoint;

@Produce(uri = "direct:userdata.soap.requests")
ProducerTemplate channel;

....

private Object sendRequest(Object request, String operationName) throws Exception{
    Exchange inExchange = endpoint.createExchange(ExchangePattern.InOnly);
    inExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, operationName);
    inExchange.getIn().setHeader(CxfConstants.OPERATION_NAMESPACE, "http://tempuri.org/");
    inExchange.getIn().setBody(request);

    Map<String, Object> context = new HashMap<>();
    context.put("ws-security.username", soapUsername);
    context.put("ws-security.password", soapPassword);
    inExchange.getIn().setHeader(Client.REQUEST_CONTEXT, context);

    Exchange outExchange = channel.send(inExchange);
    log.error(outExchange.getOut().getBody(String.class));
    Object result = outExchange.getIn().getBody(Object.class);
    if(result.getClass().equals(FaultException.class)){
        throw (FaultException) result;
    }
    return result;
}

其中endpointorg.apache.camel.Endpoint类型,channelorg.apache.camel.ProducerTemplate类型

request-Object 是插件自动生成的类的类型。

我也尝试过,编写自己的 WSS4JOutInterceptor 来处理安全部分,但这也没有用。

如果我需要提供更多信息,请告诉我。

提前谢谢了

【问题讨论】:

    标签: soap apache-camel cxf ws-security camel-cxf


    【解决方案1】:

    事实证明,在解释 SOAP 答案时出现了问题。 所以实际上这条路线是这样的。只需设置标头ws-security.usernamews-security.password,cxf 将负责创建正确的标头。 我还将数据格式更改为PAYLOAD,此时不需要编组。

    无论如何感谢阅读

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 2018-06-02
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多