使用WCF客户端的WS-Security Web服务

时间:2018-07-25 16:21:08

标签: c# .net wcf x509 ws-security

我设法使用WS-Security 1.1协议使用基于Java的Web服务(第三方)。该Web服务仅需要通过x509证书进行签名,而无需进行加密。 但是我遇到了这个错误:

  

签名确认元素不能在主签名之后出现。

捕获的服务器响应包如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true">
            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-501">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <ds:Reference URI="#id-502">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>...</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference URI="#SigConf-500">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>...</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>
                ...
                </ds:SignatureValue>
                <ds:KeyInfo Id="KeyId-...">
                    <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-...">
                        <ds:X509Data>
                            <ds:X509IssuerSerial>
                                <ds:X509IssuerName>CN=COMODO RSA Organization Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB</ds:X509IssuerName>

                                <ds:X509SerialNumber>...</ds:X509SerialNumber>
                            </ds:X509IssuerSerial>
                        </ds:X509Data>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
            <wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" Value="..." wsu:Id="SigConf-500"/>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-502">
        <altaClienteResponse xmlns="...">
            <altaClienteReturn>
                <codigoError>7</codigoError>
                <descripcionError>El código de banco no es válido.</descripcionError>
                <idTransaccion xsi:nil="true"/>
            </altaClienteReturn>
        </altaClienteResponse>
    </soapenv:Body>
</soapenv:Envelope>

服务器正在响应应有的响应,但是我的应用似乎无法正确解释它。看来<wsse11:SignatureConfirmation .../>标签必须在<ds:Signature></ds:Signature>标签之前。

我找不到与此订单标准有关的任何信息。

编辑:添加我的代码。

try
{
    var certificate = new X509Certificate2(@"C:\Users\...\cert.pfx", PassKeyStore);

    var binding = new CustomBinding();

    var security = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);

    security.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters
    {
        InclusionMode = SecurityTokenInclusionMode.Never,
        ReferenceStyle = SecurityTokenReferenceStyle.Internal,
    });

    security.RecipientTokenParameters.InclusionMode = SecurityTokenInclusionMode.Never;
    security.RecipientTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;

    security.MessageSecurityVersion =
        MessageSecurityVersion.
            WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
    security.IncludeTimestamp = false;
    security.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;    

    security.RequireSignatureConfirmation = true;
    security.AllowSerializedSigningTokenOnReply = true;   

    binding.Elements.Add(security);
    binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
    binding.Elements.Add(new HttpsTransportBindingElement());    

    var client = new SistarbancService.WsMediosPagoClient(binding, new EndpointAddress(new Uri(UrlSistarbanc), new DnsEndpointIdentity("..."), new AddressHeaderCollection()));    

    client.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("C:\\Users\\...\\servidor.cer");
    client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
        System.ServiceModel.Security.X509CertificateValidationMode.None;
    client.ClientCredentials.ClientCertificate.Certificate = certificate;

    client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign;

    var response = await client.altaClienteAsync("XXX", "0", "0", "0", "0", "0");
}
catch (Exception ex)
{

}

1 个答案:

答案 0 :(得分:1)

ReceiveSecurityHeader类抛出该异常-在此处查看其源代码: https://referencesource.microsoft.com/#system.servicemodel/system/servicemodel/Security/ReceiveSecurityHeader.cs

搜索SignatureConfirmationsOccursAfterPrimarySignature并查看以下行:

    if (this.orderTracker.PrimarySignatureDone)
    {
        throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SignatureConfirmationsOccursAfterPrimarySignature)), this.Message);
    }

我也找不到任何支持此标准的标准的引用...

您最好向Microsoft问这个问题。