WCF over TCP,具有用户名验证且没有证书

时间:2011-04-19 23:23:15

标签: wcf nettcpbinding

我正在使用WCF进行各种.NET应用程序之间的通信。这些服务都在同一个私有子网上,因此我想避免加密和证书的复杂性和性能开销。但是,我需要基本的用户名/密码支持,因为请求都是根据我们的自定义MembershipProvider进行身份验证。

我们目前正在使用带有Clear Username Binding的HTTP,而且运行良好。但是,我想使用TCP来提高性能。是否可以在Clear Username Binding上进行简单的用户名/密码身份验证(NetTcpBinding的方式),而无需使用证书,加密等?

1 个答案:

答案 0 :(得分:5)

我最终使用的解决方案是修改Clear Username Binding以使用TCP进行传输和二进制消息编码。我从series of comments上的the author's blog得到了这个想法。我的绑定的完整代码如下:

using System;
using System.Configuration;
using System.Net.Security;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;

namespace ClearTcpBinding
{
    public class ClearTcpBinding : CustomBinding
    {
        private long _maxReceivedMessageSize = 65536;

        public void SetMaxReceivedMessageSize(long value)
        {
            _maxReceivedMessageSize = value;
        }

        public override BindingElementCollection CreateBindingElements()
        {
            var res = new BindingElementCollection
                          {
                              new BinaryMessageEncodingBindingElement {MessageVersion = MessageVersion.Soap12WSAddressing10},
                              SecurityBindingElement.CreateUserNameOverTransportBindingElement(),
                              new AutoSecuredTcpTransportElement {MaxReceivedMessageSize = _maxReceivedMessageSize}
                          };
            return res;
        }

        public override string Scheme { get { return "net.tcp"; } }
    }

    public class ClearTcpBindingElement : StandardBindingElement
    {
        private ConfigurationPropertyCollection _properties;

        protected override void OnApplyConfiguration(Binding binding)
        {
            var b = (ClearTcpBinding)binding;
            b.SetMaxReceivedMessageSize(Convert.ToInt64(MaxReceivedMessageSize));
        }

        protected override Type BindingElementType
        {
            get { return typeof(ClearTcpBinding); }
        }

        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                if (_properties == null)
                {
                    var properties = base.Properties;
                    properties.Add(new ConfigurationProperty("maxReceivedMessageSize", typeof(string), "65536"));
                    _properties = properties;
                }
                return _properties;
            }
        }

        public string MaxReceivedMessageSize
        {
            get { return (string)base["maxReceivedMessageSize"]; }
            set { base["maxReceivedMessageSize"] = value; }
        }
    }

    public class ClearTcpCollectionElement
        : StandardBindingCollectionElement<ClearTcpBinding, ClearTcpBindingElement>
    {
    }

    public class AutoSecuredTcpTransportElement : TcpTransportBindingElement, ITransportTokenAssertionProvider
    {
        public override T GetProperty<T>(BindingContext context)
        {
            if (typeof(T) == typeof(ISecurityCapabilities))
                return (T)(ISecurityCapabilities)new AutoSecuredTcpSecurityCapabilities();
            return base.GetProperty<T>(context);
        }

        public System.Xml.XmlElement GetTransportTokenAssertion()
        {
            return null;
        }
    }

    public class AutoSecuredTcpSecurityCapabilities : ISecurityCapabilities
    {
        public ProtectionLevel SupportedRequestProtectionLevel { get { return ProtectionLevel.EncryptAndSign; } }
        public ProtectionLevel SupportedResponseProtectionLevel { get { return ProtectionLevel.EncryptAndSign; } }
        public bool SupportsClientAuthentication { get { return false; } }
        public bool SupportsClientWindowsIdentity { get { return false; } }
        public bool SupportsServerAuthentication { get { return true; } }
    }
}