Camel CXF SOAP API使用者(带https和安全标头)

mrfwxfqh  于 2023-01-13  发布在  Apache
关注(0)|答案(1)|浏览(151)

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

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目标生成Java类。

<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依赖项:
Camel 版本:2.20.3
一个三个三个一个
我试着通过SoapUI连接到api,一切都很好,无论是SoapUI的身份验证部分,还是在SoapHeader中指定安全部分,都很好用。
我的 Camel 路线构建器如下所示:

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来处理安全部分,但这也不起作用。
如果我需要提供更多信息,请告诉我。
先谢谢你了

pgvzfuti

pgvzfuti1#

结果是,在解释SOAP应答时出现了问题。因此,实际上路由是这样工作的。只需设置标头ws-security.usernamews-security.password,cxf将负责创建正确的标头。我还将数据格式更改为PAYLOAD,此时不需要编组。
无论如何谢谢你的阅读

相关问题