Java Web服务客户端使用需要标题和正文签名的WCF服务

时间:2015-04-04 09:16:23

标签: java c# web-services wcf wsdl

我们正在开发的系统包含以下应用程序: - 可以发布WSTrust访问令牌的.Net WCF安全令牌服务。 - 公开简单Ping操作的Java服务。 - 一个Java servlet,它调用STS获取令牌,然后使用它来访问服务。

.Net WCF STS的要求: - 必须签署请求和响应的消息正文。 - 没有加密。 - 必须有时间戳,必须签名。 - 必须使用https。

为了满足这些要求,我们制作了一个自定义WCF Web服务,其自定义绑定为:

        var bindings = new BindingElementCollection();
        var transportBinding = new HttpsTransportBindingElement { RequireClientCertificate = false };
        var encodingBinding = new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.Soap12WSAddressing10 };
        MessageSecurityVersion version =
            MessageSecurityVersion
                .WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;

        var sec = SecurityBindingElement.CreateMutualCertificateBindingElement(version) as AsymmetricSecurityBindingElement;
        sec.MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;

        bindings.Add(sec);
        bindings.Add(encodingBinding);
        bindings.Add(transportBinding);

服务主机初始化如下:

        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IWSTrust13SyncContract),
              new MyCustomBinding(), "/myendpoint");
        endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;

到目前为止一切顺利。我们使用.Net客户端进行了测试,结果非常好。对于Java部分,结果并不那么好。 到目前为止我们所做的所有步骤都是:

  1. 在Java服务中:编辑Web服务属性:

    • 使用“STS颁发的背书令牌”机制设置安全服务
    • 设置KeyStore和TrustStore
  2. 在servlet应用程序中

    • 使用Java服务的wsdl添加Web服务客户端 - >编辑Web服务属性
    • 设置安全性:密钥库和信任库
    • 设置安全令牌服务:端点,wsdl位置,服务名称,端口名称,命名空间和ws信任版本

    • 使用STS'wsdl - >添加Web服务客户端编辑Web服务属性

    • 在“服务质量”标签中,只有“传输”部分。 “安全”部分不存在。的(1)
  3. 设置完所有上述选项后,检查文件夹“Src / java / META - INF”,有预期的wsit-client.xml和2个服务引用xml文件

    • 我已经检查了在xml文件上生成的策略,所有看起来都没问题,它的策略与我们STS的wsdl相同。详情请见:
    • AsymmetricBinding
    • 和SignedParts
    • TransportBinding
    • ...
  4. 最后一步是启动服务端口并按如下方式调用操作 Service_Service service = new Service_Service();     Service stub = service.getServicePort();     return stub.ping();
  5. 我预计在发送到STS之前,邮件将被签名(标题和正文)。但实际上,发送给STS的消息未签名。 STS抛出一个错误:     “具有'_1'id的安全标头元素'Timestamp'必须签名”(2)

    如果我们更改为使用http而不是https进行传输绑定,则会正确签署对STS的请求消息。但要求是使用https。

    我们的问题是:

    • (1):QoS选项卡中没有安全部分正常吗?或者我们在这里做错了什么?
    • (2):如何在使用https时让Java签署正文和标题的其他元素?

1 个答案:

答案 0 :(得分:0)

事实证明,该服务以及Java客户端没有任何问题。暴露的WSDL导致了所有麻烦。简而言之,WSDL同时具有AsymmetricBinding和TransportBinding元素,这使得客户端在尝试使用WSDL时感到困惑。从WSDL中删除TransportBinding元素后,Java客户端可以使用WSDL并使用签名生成正确的请求。