WCF через TCP с аутентификацией по имени пользователя и без сертификатов - PullRequest
2 голосов
/ 20 апреля 2011

Я использую WCF для связи между различными приложениями .NET.Все эти службы находятся в одной частной подсети, поэтому я хотел бы избежать сложности и снижения производительности шифрования и сертификатов.Однако мне нужна базовая поддержка имени пользователя и пароля, поскольку все запросы аутентифицируются на нашем обычном MembershipProvider .

В настоящее время мы используем HTTP с Очистить привязку имени пользователя иэто работает хорошо.Тем не менее, я хотел бы использовать TCP для повышения производительности.Можно ли выполнить простую аутентификацию по имени пользователя / паролю (как Очистить привязку имени пользователя делает) через NetTcpBinding без использования сертификатов, шифрования и т. Д.?

1 Ответ

5 голосов
/ 29 апреля 2011

Решением, которое я в итоге выбрал, было изменение Очистить привязку имени пользователя для использования TCP для транспорта и двоичного кодирования сообщений.Я получил идею из серии комментариев на в блоге автора .Полный код для моей привязки ниже:

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; } }
    }
}
...