2

我正在尝试使用 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

还有其他方法可以设置用户名令牌吗?

PD对不起我的英语...

4

1 回答 1

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 专有解决方案,但到目前为止,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

于 2014-11-13T20:41:22.130 回答