使用 WSFederationHttpBinding 的性能非常糟糕 - IIS 每秒仅处理 250 个请求。
捆绑:
public class CustomFactoryActive : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost host = new ServiceHost(serviceType, baseAddresses);
CommonConf.ConfigureServiceHost(host);
string issuerAddress = ConfigManager.ActiveSTS;
string issuerMexAddress = issuerAddress + "/mex";
WSFederationHttpBinding wsFedBinding = new WSFederationHttpBinding();
wsFedBinding.Security.Mode = WSFederationHttpSecurityMode.Message;
wsFedBinding.ReliableSession.Enabled = false;
wsFedBinding.MaxReceivedMessageSize = wsFedBinding.MaxBufferPoolSize = Constants.MaxFileSize;
XmlDictionaryReaderQuotas quotas = wsFedBinding.ReaderQuotas;
quotas.MaxArrayLength = quotas.MaxBytesPerRead = quotas.MaxStringContentLength =
quotas.MaxNameTableCharCount = quotas.MaxDepth = (int)Constants.MaxFileSize;
var messageSecurity = wsFedBinding.Security.Message;
messageSecurity.IssuedTokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1";
messageSecurity.IssuedKeyType = SecurityKeyType.SymmetricKey;
messageSecurity.EstablishSecurityContext = false;
messageSecurity.NegotiateServiceCredential = false;
messageSecurity.IssuerAddress = new EndpointAddress(new Uri(issuerAddress));
messageSecurity.IssuerMetadataAddress = new EndpointAddress(new Uri(issuerMexAddress));
WS2007HttpBinding ws2007HttpBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
var wsHttpSecurity = ws2007HttpBinding.Security;
wsHttpSecurity.Message.ClientCredentialType = MessageCredentialType.UserName;//авторизация по логину и паролю
wsHttpSecurity.Message.NegotiateServiceCredential = true;
wsHttpSecurity.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
messageSecurity.IssuerBinding = ws2007HttpBinding;
ContractDescription contractDescription = ContractDescription.GetContract(typeof(ISignService));
EndpointAddress endpointAddress = new EndpointAddress(baseAddresses[0]);
ServiceEndpoint endpoint = new ServiceEndpoint(contractDescription, wsFedBinding, endpointAddress);
host.Description.Endpoints.Add(endpoint);
return host;
}
}
我的 wcf 测试方法什么都不做 - 它只返回 1 个字节。
但是,当我使用简单的WSHttpBinding和消息安全性而没有任何WIF saml令牌时,我每秒收到大约4000个请求
我无法忍受为什么
应设置和配置 WCF 跟踪 若要查看在 WCF 体系结构中花费时间的概述,有关详细信息,请参阅 http://msdn.microsoft.com/en-us/library/ms733025.aspx。
启用跟踪并查看请求时,您可能会看到(在单个调用方多次调用同一服务的测试环境中)STS 仅被调用一次,后续调用包含缓存的令牌。但是,所有调用仍将设置安全连接,从而验证每个调用的令牌(这将需要一些 CPU 时间)。或者,您可以/可以通过方法级分析服务主机来验证所有这些,这将更清楚地显示时间的确切花费位置。
模拟安全令牌(不要使用实际的 STS),看看你的性能如何。我假设那部分是你的瓶颈。
我看到一个案例,NegotiateServiceCredential = true
打开频道时添加了多个网络往返。尝试将wsHttpSecurity.Message.NegotiateServiceCredential
更改为false
,并在客户端指定服务证书。
证书的验证也可能花费大量时间。您可以尝试更改客户端的行为,以便跳过证书验证和吊销。
//Client
var clientCredentialsBehavoir = behaviors.Find<FederatedClientCredentials>();
clientCredentialsBehavoir.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
clientCredentialsBehavoir.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
//The same can be done on the server
var serviceConfiguration = new ServiceConfiguration();
serviceConfiguration.CertificateValidationMode = X509CertificateValidationMode.None;
这不应该在生产环境中完成!
您也可以通过应用程序配置执行此操作。
SAML 令牌是加密的 - 如何取决于您的配置。就您而言,您似乎正在使用SecurityAlgorithmSuite.Default
,我认为这是AES256
.
每当发生解密/加密时,CPU 都需要一些时间来处理数字。它所需的时间/精力取决于广泛的因素,但我不认为你看到你所看到的请求处理能力的差异是多么不寻常。
正如其他响应所提到的,即使缓存了令牌,令牌仍必须经过验证和解密,每个响应都涉及通过一个或多个算法运行令牌的内容。
我的建议:使用不同的SecurityAlgorithmSuite
常量执行一些分析,并比较结果。
一个起点可能是将SecurityAlgorithmSuite.Basic128
与.Basic256
进行比较。256
常量等效于默认选项。