在WCF SOAP消息中,如何包含内联证书密钥(没有引用令牌)?

时间:2016-01-11 09:21:21

标签: c# wcf soap ws-security

enter image description here

我需要一个C#配置,它会生成屏幕截图第三部分显示的信封。目前我只能接近前两个所示。我当前的配置:

using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using System.ServiceModel.Security.Tokens;
using System.Text;



public class CustomAlgorithmSuite : SecurityAlgorithmSuite
{
    public override string DefaultAsymmetricKeyWrapAlgorithm    { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
    public override string DefaultAsymmetricSignatureAlgorithm  { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
    public override string DefaultCanonicalizationAlgorithm     { get { return "http://www.w3.org/2001/10/xml-exc-c14n#"; }}
    public override string DefaultDigestAlgorithm               { get { return "http://www.w3.org/2000/09/xmldsig#sha1"; }}
    public override string DefaultEncryptionAlgorithm           { get { return "http://www.w3.org/2001/04/xmlenc#aes256-cbc"; }}
    public override int    DefaultEncryptionKeyDerivationLength { get { return SecurityAlgorithmSuite.Default.DefaultEncryptionKeyDerivationLength; }}
    public override int    DefaultSignatureKeyDerivationLength  { get { return SecurityAlgorithmSuite.Default.DefaultSignatureKeyDerivationLength; }}
    public override int    DefaultSymmetricKeyLength            { get { return SecurityAlgorithmSuite.Default.DefaultSymmetricKeyLength; }}
    public override string DefaultSymmetricKeyWrapAlgorithm     { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
    public override string DefaultSymmetricSignatureAlgorithm   { get { return "http://www.w3.org/2000/09/xmldsig#dsa-sha1"; }}
    public override bool   IsAsymmetricKeyLengthSupported(int length) { return true; }
    public override bool   IsSymmetricKeyLengthSupported(int length)  { return true; }
}



class Program
{
    static void Main()
    {
        X509SecurityTokenParameters x509Params = new X509SecurityTokenParameters()
        {
            X509ReferenceStyle = X509KeyIdentifierClauseType.RawDataKeyIdentifier,
            InclusionMode      = SecurityTokenInclusionMode.AlwaysToRecipient,
            ReferenceStyle     = SecurityTokenReferenceStyle.External,
            RequireDerivedKeys = false
        };

        SecurityBindingElement security = new TransportSecurityBindingElement()
        {
            MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10,
            DefaultAlgorithmSuite  = new CustomAlgorithmSuite()
        };
        security.EndpointSupportingTokenParameters.Endorsing.Add(x509Params);
        security.SetKeyDerivation(false);
        //security.IncludeTimestamp = false;

        TextMessageEncodingBindingElement encoding = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
        HttpsTransportBindingElement transport = new HttpsTransportBindingElement();
        //transport.RequireClientCertificate = true;
        CustomBinding customBinding = new CustomBinding(security, encoding, transport);

        ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;

        var twoCertificatesInOneFile = new X509Certificate2Collection();
        twoCertificatesInOneFile.Import("foo path", "foo cert pass", X509KeyStorageFlags.Exportable);
        someGeneratedServiceClass client = new someGeneratedServiceClass(customBinding, new EndpointAddress(new Uri("foo webservice address"), EndpointIdentity.CreateDnsIdentity(twoCertificatesInOneFile[0].FriendlyName)));
        client.ClientCredentials.ServiceCertificate.DefaultCertificate = twoCertificatesInOneFile[0];
        client.ClientCredentials.ClientCertificate.Certificate = twoCertificatesInOneFile[1];
        //client.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.None;
        client.ClientCredentials.UserName.UserName = "foo user";
        client.ClientCredentials.UserName.Password = "foo pass";

        client.someServiceCall("foo", "foo", false, out i1, out i2);
    }
}

我是否遗失了任何财产,或者我是否必须为此工作实施自定义令牌/编码器?

1 个答案:

答案 0 :(得分:0)

这与this question的答案相同。

没有标准的方法来实现这种非标准的实现,所以我最终手动重写部分生成的SOAP消息。