【发布时间】: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;
}
其中endpoint是org.apache.camel.Endpoint类型,channel是org.apache.camel.ProducerTemplate类型
request-Object 是插件自动生成的类的类型。
我也尝试过,编写自己的 WSS4JOutInterceptor 来处理安全部分,但这也没有用。
如果我需要提供更多信息,请告诉我。
提前谢谢了
【问题讨论】:
标签: soap apache-camel cxf ws-security camel-cxf