我正在尝试用Apache-CXF-2.7.11构建一个与.NET WCF服务通信的Java客户端。
我的Java客户端代码如下,客户端是自动生成IDE,只有我从CXF文档中复制的凭据。
public static void main(String args[]) throws java.lang.Exception {
URL wsdlURL = Reportes.WSDL_LOCATION;
if (args.length > 0 && args[0] != null && !"".equals(args[0])) {
File wsdlFile = new File(args[0]);
try {
if (wsdlFile.exists()) {
wsdlURL = wsdlFile.toURI().toURL();
} else {
wsdlURL = new URL(args[0]);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Reportes ss = new Reportes(wsdlURL, SERVICE_NAME);
IReportes port = ss.getWSHttpBindingIReportes();
Client client = ClientProxy.getClient(port);
Endpoint cxfEndpoint = client.getEndpoint();
Map ctx = ((BindingProvider)port).getRequestContext();
ctx.put("ws-security.username", "username");
ctx.put("ws-security.password", "password");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(ctx);
cxfEndpoint.getOutInterceptors().add(wssOut);
{
System.out.println("Invoking programaProveedores...");
java.lang.String _programaProveedores_idBeneficiario = "";
com.wsclient.ArrayOfProgramaProveedor _programaProveedores__return = port.programaProveedores(_programaProveedores_idBeneficiario);
System.out.println("programaProveedores.result=" + _programaProveedores__return);
}
System.exit(0);
}
结果是一个例外:
Advertencia: Interceptor for {http://schemas.xmlsoap.org/ws/2005/02/trust/wsdl}SecurityTokenService#{http://schemas.xmlsoap.org/ws/2005/02/trust/wsdl}RequestSecurityToken has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: No signature token
at org.apache.cxf.ws.security.wss4j.policyhandlers.SymmetricBindingHandler.doSignBeforeEncrypt(SymmetricBindingHandler.java:398)
at org.apache.cxf.ws.security.wss4j.policyhandlers.SymmetricBindingHandler.handleBinding(SymmetricBindingHandler.java:124)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:173)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:90)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:570)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:479)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
at org.apache.cxf.ws.security.trust.AbstractSTSClient.issue(AbstractSTSClient.java:782)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:62)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:56)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:52)
at org.apache.cxf.ws.security.policy.interceptors.SecureConversationOutInterceptor.issueToken(SecureConversationOutInterceptor.java:167)
at org.apache.cxf.ws.security.policy.interceptors.SecureConversationOutInterceptor.handleMessage(SecureConversationOutInterceptor.java:69)
at org.apache.cxf.ws.security.policy.interceptors.SecureConversationOutInterceptor.handleMessage(SecureConversationOutInterceptor.java:44)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:570)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:479)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
at com.sun.proxy.$Proxy38.programaProveedores(Unknown Source)
at com.wsclient.IReportes_WSHttpBindingIReportes_Client.main(IReportes_WSHttpBindingIReportes_Client.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.apache.cxf.ws.policy.PolicyException: No signature token
还有其他设置用户名令牌的方法吗?
对不起我的英文...
答案 0 :(得分:1)
我发现了问题,我想要做的是从Java客户端导入WCF创建的WSDL,最初我使用wsimport,之后我使用Metro 2.3.0并且我得到了以下错误:
Advertencia: SP0100: Policy assertion Assertion[com.sun.xml.ws.policy.sourcemodel.DefaultPolicyAssertionCreator$DefaultPolicyAssertion] {
assertion data {
namespace = 'http://schemas.microsoft.com/ws/2005/07/securitypolicy'
prefix = 'mssp'
local name = 'SslContextToken'
value = 'null'
optional = 'false'
ignorable = 'false'
attributes {
name = 'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy:IncludeToken', value = 'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient'
}
}
no parameters
nested policy {
namespace version = 'v1_5'
id = 'null'
name = 'null'
vocabulary {
1. entry = 'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy:RequireDerivedKeys'
}
assertion set {
Assertion[com.sun.xml.ws.policy.sourcemodel.DefaultPolicyAssertionCreator$DefaultPolicyAssertion] {
assertion data {
namespace = 'http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'
prefix = 'sp'
local name = 'RequireDerivedKeys'
value = 'null'
optional = 'false'
ignorable = 'false'
no attributes
}
no parameters
no nested policy
}
}
}
} is not supported under Token assertion.
原因是WCF WS-Policy正在构成这一部分:
<mssp:SslContextToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient" xmlns:mssp="http://schemas.microsoft.com/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:RequireDerivedKeys/>
</wsp:Policy>
</mssp:SslContextToken>
这意味着您的WCF服务使用X.509证书协商。在这种情况下,客户端使用服务器X.509证书进行加密。这里的独特之处在于客户端不需要带外此证书(在大多数情况下),而是使用SOAP级协商获得此证书。这是作为WS-Trust的扩展实现的。虽然这不是严格意义上的Microsoft专有解决方案,但到目前为止,微软是唯一一个实施它的解决方案。简而言之 - X.509协商(SslContextToken)不可互操作。要关闭它,请更新您的WsHttpBinding配置:
<bindings>
<wsHttpBinding>
<binding>
<security mode="Message">
<message clientCredentialType="None" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
或者在CustomBinding中选择正确的方案:
<security authenticationMode="AnonymousForCertificate">
<secureConversationBootstrap />
</security>
您还可以使用等效案例进行用户名验证。请注意,任何客户端(包括WCF客户端)现在都需要在带外定义服务证书。
此问题的引用是http://webservices20.blogspot.mx/2008/10/interoperability-gotcha-sslcontexttoken.html