我目前面临的问题是,我无法通过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;
}
其中endpoint
为org.apache.camel.Endpoint
类型,channel
为org.apache.camel.ProducerTemplate
类型request
-Object的类型来自插件自动生成的类。
我也尝试过,编写自己的WSS4JOutInterceptor来处理安全部分,但这也不起作用。
如果我需要提供更多信息,请告诉我。
先谢谢你了
1条答案
按热度按时间pgvzfuti1#
结果是,在解释SOAP应答时出现了问题。因此,实际上路由是这样工作的。只需设置标头
ws-security.username
和ws-security.password
,cxf将负责创建正确的标头。我还将数据格式更改为PAYLOAD
,此时不需要编组。无论如何谢谢你的阅读