C# ClientMessageInspector添加二进制安全令牌和签名

C# ClientMessageInspector添加二进制安全令牌和签名,c#,.net,wcf,security,wcf-security,C#,.net,Wcf,Security,Wcf Security,我正试图在桌面应用程序中使用C#使用Java Web服务。 正在使用WebServicesClientProtocol,但我无法添加WSSE用户名和令牌安全规范1.1所需的必要属性 我需要创建具有以下结构的请求: <soap:Envelope xmlns:dz="http://dom.query.api.com" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://dz.api.swd.zbp.pl/

我正试图在桌面应用程序中使用C#使用Java Web服务。
正在使用WebServicesClientProtocol,但我无法添加WSSE用户名和令牌安全规范1.1所需的必要属性

我需要创建具有以下结构的请求:

<soap:Envelope xmlns:dz="http://dom.query.api.com" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://dz.api.swd.zbp.pl/xsd">
    <soap:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-E94CEB6F4708FB7C23148611494797612">
                <wsse:Username>my_login</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">XqEwZ/CxaBfFvh487TjvN8qD63c=</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">JzURe0CxvzRjmEcH/ndldw==</wsse:Nonce>
                <wsu:Created>2017-02-09T09:42:27.976Z</wsu:Created>
            </wsse:UsernameToken>
            <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="X509-E94CEB6F4708FB7C2314861149479517">MIIKnDCCB.........nmIngeg6d6TNI=</wsse:BinarySecurityToken>
            <ds:Signature Id="SIG-E94CEB6F4708FB7C23148611494795311" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <ec:InclusiveNamespaces PrefixList="dz soap xsd" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    </ds:CanonicalizationMethod>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <ds:Reference URI="#id-E94CEB6F4708FB7C23148611494795310">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                                <ec:InclusiveNamespaces PrefixList="dz xsd" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>mlABQuNUFOmLqsDswxXxQ6XnjpQ=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>lYhBHSQ/L...XL1HEbMQjJ/Q2Rvg==</ds:SignatureValue>
                <ds:KeyInfo Id="KI-E94CEB6F4708FB7C2314861149479518">
                    <wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="STR-E94CEB6F4708FB7C2314861149479519" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                        <wsse:Reference URI="#X509-E94CEB6F4708FB7C2314861149479517" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
            </ds:Signature>
        </wsse:Security>
    </soap:Header>
    <soap:Body wsu:Id="id-E94CEB6F4708FB7C23148611494795310" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <dz:query>
            <dz:param>
                <xsd:userQueryId>27467</xsd:userQueryId>
            </dz:param>
        </dz:query>
    </soap:Body>
</soap:Envelope>
使用上述代码,我可以创建此请求:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <wsse:Username>Demo</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">1TiCoKWfNF3EdEH3qdU4inKklaw=</wsse:Password>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">mAyz3SywR8sR9IkhDGJRIw==</wsse:Nonce>
                <wsu:Created>2017-02-09T23:29:14.371Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <query xmlns="http://dom.query.api.com">
            <param>
                <userQueryId xsi:nil="true" xmlns="http://dom.query.api.com/xsd"/>
            </param>
        </query>
    </s:Body>
</s:Envelope>

演示
1ticokwfnf3edeh3qdu4inklaw=
mAyz3SywR8sR9IkhDGJRIw==
2017-02-09T23:29:14.371Z
正如您所看到的,我的
安全性
元素中缺少
BinarySecurityToken
签名
元素。 我尝试过使用
Microsoft.Web.Services3
,但运气不佳。
例如,
BinarySecurityToken
的构造函数受到保护

我已将我的客户证书导入我的证书存储区。我只需要在我请求的正文上签字

如何将这两个元素添加到
标题中的
安全
元素?我知道我必须使用
Microsoft.Web.Services3
,但我不知道如何使用


我在互联网上搜索过类似的问题,但我找到的只是关于如何添加用户名和密码的教程,关于添加
签名
二进制安全令牌
的问题仍然没有答案-

此编码绑定应该会产生类似的消息:

var b = new CustomBinding();

            var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
            sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
            sec.MessageSecurityVersion =
                MessageSecurityVersion.
                    WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
            sec.IncludeTimestamp = false;
            sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;

            b.Elements.Add(sec);
            b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
            b.Elements.Add(new HttpsTransportBindingElement());


            var c =
                new ServiceReference1.SimpleServiceSoapClient(b, new EndpointAddress(new Uri("https://www.bankhapoalim.co.il/"), new DnsEndpointIdentity("WSE2QuickStartServer"), new AddressHeaderCollection()));

            c.ClientCredentials.UserName.UserName = "yaron";
            c.ClientCredentials.UserName.Password = "1234";

            c.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
                System.ServiceModel.Security.X509CertificateValidationMode.None;
            c.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(@"C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates\Server Public.cer");

            c.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@"C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates\Client Private.pfx", "wse2qs");

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

您选择的路径将要求您自己实现更难的消息签名。

非常感谢您的回复。由代码创建的请求看起来很好,缺少的一件事是UsernameToken中的
Nonce
。我是否应该使用自定义
WSSecurityTokenSerializer
?如图所示:。我需要安全标题中的
Nonce
和签名正文。不确定该链接是否有效,您应该尝试。Otherwise应该有其他方法在wcf中创建自定义用户名令牌,如。另外,如果您自己在消息检查器中创建用户名,它仍然有效(在本例中,将其从代码配置中删除)。另一个选项是实现一个自定义编码器,它将nonce添加到用户名(用作基数),但小心地使用空格,以免使签名无效。我尝试使用我的
MessageInspector
,但它在
s:Header
中创建了两个
o:Security
标记,一个包含
o:UsernameToken
Nonce
的,第二个没有它,但是包含
BinarySecurityToken
Signature
的,WSSecurityTokenSerializer
看起来很有前途(它以我想要的方式序列化了
UsernameToken
),但我注意到了BinarySecurityToken中的一些差异。使用您的代码,我只有
ValueType
属性的值
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3
但在我从服务所有者那里得到的示例请求中,此属性应该有值
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1
和带有值的
编码类型http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary
感谢您的帮助。我仍然有问题,但由于你的回答,我离你更近了。我会检查证书和所有我能检查的东西。如果它不起作用,我将在单独的问题中发布我的代码。再次感谢!
var b = new CustomBinding();

            var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
            sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
            sec.MessageSecurityVersion =
                MessageSecurityVersion.
                    WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
            sec.IncludeTimestamp = false;
            sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;

            b.Elements.Add(sec);
            b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
            b.Elements.Add(new HttpsTransportBindingElement());


            var c =
                new ServiceReference1.SimpleServiceSoapClient(b, new EndpointAddress(new Uri("https://www.bankhapoalim.co.il/"), new DnsEndpointIdentity("WSE2QuickStartServer"), new AddressHeaderCollection()));

            c.ClientCredentials.UserName.UserName = "yaron";
            c.ClientCredentials.UserName.Password = "1234";

            c.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
                System.ServiceModel.Security.X509CertificateValidationMode.None;
            c.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(@"C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates\Server Public.cer");

            c.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@"C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates\Client Private.pfx", "wse2qs");

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