c# - WCF 服务中未调用自定义 x509CertificateValidator 验证
问题描述
WCF 服务使用具有自签名证书的证书安全性。从谷歌搜索来看,默认验证器似乎应该失败,但服务是正常的。我找不到任何地方设置了certificateValidationMode 来更改此默认行为,或识别任何其他会更改它的东西,所以我很困惑。
我已将 WCF 服务配置为使用自定义 x509CertificateValidator 来验证证书。但是没有调用 Validate() 方法。我的问题是 - 为什么没有调用 Validate 方法?
我之前没有为 WCF 服务配置证书安全性,所以我可能遗漏了一些明显的东西。我怀疑问题出在代码中的其他地方,但我不知道还要寻找什么。
这是我设置自定义验证器的地方:
viewerHost = new ServiceHost(typeof(ViewerService));
viewerHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
viewerHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CertValidator();
viewerHost.AddServiceEndpoint(
typeof(IViewerService),
getBinding(true, true),
@"net.tcp://localhost:8746/Viewer/");
setCertificate(viewerHost);
addThrottlingBehaviour(viewerHost);
viewerHost.Open();
以下是上述摘录中 getBinding() 的代码,试图将凭证类型设置为注释掉(它完全停止了连接,而没有调用 Validate() 方法):
private static CustomBinding getBinding(bool useCompression, bool useSSL)
{
BindingElementCollection elements = new BindingElementCollection();
/* I tried the following after reading CodeCaster's comment, which did not work:
SecurityBindingElement security =
SecurityBindingElement.CreateCertificateOverTransportBindingElement();*/
// MessageEncoding
BinaryMessageEncodingBindingElement binaryMessageEncodingBE = new BinaryMessageEncodingBindingElement();
if (useCompression)
{
GZipMessageEncodingBindingElement gZipMessageEncodingBE = new GZipMessageEncodingBindingElement(binaryMessageEncodingBE);
elements.Add(gZipMessageEncodingBE);
}
else
{
elements.Add(binaryMessageEncodingBE);
}
if (useSSL)
{
SslStreamSecurityBindingElement sslStreamSecurityBE = new SslStreamSecurityBindingElement();
sslStreamSecurityBE.SslProtocols = SslProtocols.Tls11; // Currently MD5 certs are in use. This will be changed when they are replaced with SHA256 ones.
elements.Add(sslStreamSecurityBE);
}
// TcpTransportBindingElement
TcpTransportBindingElement tcpTransportBE = new TcpTransportBindingElement();
tcpTransportBE.MaxReceivedMessageSize = 1048576;
tcpTransportBE.ListenBacklog = 1000;
tcpTransportBE.MaxPendingConnections = 1000;
tcpTransportBE.MaxPendingAccepts = 1000;
tcpTransportBE.ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint = 1000;
elements.Add(tcpTransportBE);
CustomBinding binding = new CustomBinding(elements);
BindingContext context = new BindingContext(binding, new BindingParameterCollection());
XmlDictionaryReaderQuotas quotas = binaryMessageEncodingBE.GetProperty<XmlDictionaryReaderQuotas>(context);
quotas.MaxArrayLength = 1048576;
quotas.MaxStringContentLength = 1048576;
return binding;
}
setCertificate() 实现:
/// <summary>
/// Sets a server certificate for a service host
/// </summary>
/// <param name="serviceHost"></param>
private static void setCertificate(ServiceHost serviceHost)
{
// A certificate has to be installed on the server. This certificate is used for SSL encryption
serviceHost.Credentials.ServiceCertificate.SetCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
"localhost");
var test = serviceHost.Credentials.ServiceCertificate.Certificate;
}
解决方案
推荐阅读
- javascript - 是否有 App 会在 React Native 中隐藏/显示?切换应用程序时删除键盘侦听器的问题
- python - Django 找不到模块“learning_logs”的问题
- docker - 从 Skopeo 容器访问本地 docker 注册表
- r - 如果它们降落在另一个点的某个附近,我如何生成点被“排斥”的数据?
- ajax - 使用 express 对谷歌云功能的 axios 请求
- javascript - 更改 [ ] 符号之间的样式的问题
- swift - 为什么 UITextFIeld 在 Swift 中返回可选值?
- javascript - Nginx(反向代理)和 Angular(使用 SSR 和 i18n) - 根据 lang cookie 值使用正确的本地化应用程序
- lldb - 为什么在 lldb 中的“命令别名 pcs 调用 ...”时出现“错误:无法创建请求的别名”?
- python - 计算回归变量的方差