WCF WebService请求:在SecurityTokenReference中添加参考标签,而不是关键标签标签



我需要使用.NET食用Java Web服务。必须签署请求,并且需要在请求中包含证书。

使用下面的'getClient'方法时,请求为Generatec正确,除了一个字段。在SecurityTokenReference元素中,添加了"关键标识符"。此SecurityTokenReference字段应包含"签名"元素中第三个重复的"参考"字段:

</o:Security>
  </s:Header>
    <o:BinarySecurityToken>...</o:BinarySecurityToken>
    <Signature>
      <SignedInfo>
        <CanonicalizationMethod></CanonicalizationMethod>
        <SignatureMethod></SignatureMethod>
        <Reference URI="#_1">...</Reference>
        <Reference URI="#uuid-001">...</Reference>
        <Reference URI="#uuid-002">...</Reference>
      </SignedInfo>
      <SignatureValue>...</SignatureValue>
      <KeyInfo>
        <o:SecurityTokenReference>
          <o:KeyIdentifier >...</o:KeyIdentifier>
        </o:SecurityTokenReference>
      </KeyInfo>
    </Signature>
  </o:Security>
</s:Header>

so

    <o:SecurityTokenReference>
      <o:KeyIdentifier >...</o:KeyIdentifier>
    </o:SecurityTokenReference>

应该是

    <o:SecurityTokenReference>
        <o:Reference ValueType="..." URI="uuid-002" />
    </o:SecurityTokenReference>

但是我无法实现此功能。

使用

 InitiatorTokenParameters InclusionMode = SecurityTokenInclusionMode.Once

添加了正确的"参考"标签,但生成了双"二进制式"标签,从而导致网络服务被拒绝。有什么解决方案吗?

public wsClient GetClient()  
{  
        CustomBinding b = new CustomBinding();
        HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
        AsymmetricSecurityBindingElement asec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement
            (MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
        asec.SetKeyDerivation(false);
        asec.AllowInsecureTransport = true;
        asec.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
        asec.IncludeTimestamp = true;
        asec.ProtectTokens = true;
        asec.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
        asec.InitiatorTokenParameters = new X509SecurityTokenParameters
        {
            InclusionMode = SecurityTokenInclusionMode.Never, //.Once, ----> Once creates correct SecurityTokenReference, but double BinarySecurityToken
            ReferenceStyle = SecurityTokenReferenceStyle.Internal
        };
        asec.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters());
        TextMessageEncodingBindingElement textMessageEncoding = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
        b.Elements.Add(asec);
        b.Elements.Add(textMessageEncoding);
        b.Elements.Add(transport);
        string url = "https://service";
        var c = new wsClient(b, new EndpointAddress(new Uri(url), 
            new DnsEndpointIdentity(kgParams.DnsEndpointIdentity), new AddressHeaderCollection()));

        X509Certificate cert = GetCertificate();
        c.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(cert);
        c.ClientCredentials.ServiceCertificate.DefaultCertificate = c.ClientCredentials.ClientCertificate.Certificate;
        c.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;
        return c;
}

在与这个问题挣扎了几天后,尽管有250分的赏金,但我只能得出这样的结论:这是Java和Java之间的不相容性.NET WCF。

最后,我只是沮丧地对WCF进行了审判,并从头开始重新创建了整个*****请求。这意味着:

  • 创建一个包含所需数据的xmldocument
  • 将证书添加为base64到标题
  • 手动时间戳请求
  • 手动添加正确的 keyInfo标签
  • 使用适当的GUIDS手动添加所有参考
  • 使用signedxml和证书手动签名所有元素
  • 手动发布请求

服务器在没有任何投诉的情况下接受了请求。

最新更新