我正在使用WCF进行各种.NET应用程序之间的通信。这些服务都在同一个私有子网上,因此我想避免加密和证书的复杂性和性能开销。但是,我需要基本的用户名/密码支持,因为请求都是根据我们的自定义MembershipProvider进行身份验证。
我们目前正在使用带有Clear Username Binding的HTTP,而且运行良好。但是,我想使用TCP来提高性能。是否可以在Clear Username Binding上进行简单的用户名/密码身份验证(NetTcpBinding的方式),而无需使用证书,加密等?
答案 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; } }
}
}