问题描述
我正在尝试使用与.NET WCF服务进行通信的Apache-CXF-2.7.11构建Java客户端.
I'm trying to buil a Java client with Apache-CXF-2.7.11 that communicates with .NET WCF services.
下面是我的Java客户端代码,客户端正在自动生成IDE,只有我从CXF文档复制的凭据.
My Java client code is following, the client were autogenerating whith the IDE, only the credentials i've copied from the CXF docs.
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
还有其他设置用户名令牌的方法吗?
There's other way to set username token?
PD很抱歉我的英语...
PD Sorry for my english...
推荐答案
我发现了问题,我想做的是从Java客户端导入WCF创建的WSDL,最初我使用的是 wsimport ,之后我使用Metro 2.3.0和我收到以下错误:
I've found the problem, what i'm trying to do is to import a WCF-created WSDL from a Java client, originally i use wsimport, after that i use Metro 2.3.0 and i get the following error:
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包含此部分:
The reason is that WCF WS-Policy was contaning this section:
<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专有解决方案,但到目前为止,Microsoft是唯一实现它的解决方案.简而言之- X.509协商(SslContextToken)无法互操作.要关闭此功能,请更新您的WsHttpBinding配置:
This means that your WCF service uses X.509 certificates negotiation. In such a scenario, clients use the server X.509 certificate for encryption. The unique here is that clients are not required to have this certificate out of band (as in most cases), rather they get this certificate using a SOAP-level negotiation. This is implemented as an extension over WS-Trust. While this is not strictly a proprietary Microsoft solution, Microsoft was the only one to implement it so far. In short - X.509 negotiation (SslContextToken) is not interoperable.To turn it off either update your WsHttpBinding configuration:
<bindings>
<wsHttpBinding>
<binding>
<security mode="Message">
<message clientCredentialType="None" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
或者在您的CustomBinding中选择正确的方案:
Or choose the correct scenario in your CustomBinding:
<security authenticationMode="AnonymousForCertificate">
<secureConversationBootstrap />
</security>
您还可以使用等效情况进行用户名身份验证.请注意,任何客户端(包括WCF客户端)现在都需要定义带外服务证书.
You can also use the equivalent cases for username authentication. Note that any clients (including WCF ones) will now need to have the service certificates defined out of band.
对此问题的引用是 http://webservices20.blogspot. mx/2008/10/interoperability-gotcha-sslcontexttoken.html
这篇关于没有签名令牌Java CXF客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!